LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* AMD viper chipset and UDMA100
@ 2001-09-27 21:26 Sean Swallow
  2001-09-27 21:36 ` Nicholas Knight
  2001-09-27 21:59 ` Vojtech Pavlik
  0 siblings, 2 replies; 10+ messages in thread
From: Sean Swallow @ 2001-09-27 21:26 UTC (permalink / raw)
  To: linux-kernel

List,

I just got a tyan tiger w/ the AMD Viper chipset on it. For some reason
Linux will only set the onboard (AMD viper) chains to UDMA33.

I'm using linux 2.4.9, and I have also tried 2.4.10. Is there a limitation
to the AMD Viper driver?

PS. The cables (2) are BRAND new ata100 cables.

cheers,

-- 
Sean J. Swallow
pgp (6.5.2) keyfile @ https://nurk.org/keyfile.txt



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

* Re: AMD viper chipset and UDMA100
  2001-09-27 21:26 AMD viper chipset and UDMA100 Sean Swallow
@ 2001-09-27 21:36 ` Nicholas Knight
  2001-09-27 21:59 ` Vojtech Pavlik
  1 sibling, 0 replies; 10+ messages in thread
From: Nicholas Knight @ 2001-09-27 21:36 UTC (permalink / raw)
  To: Sean Swallow, linux-kernel

On Thursday 27 September 2001 02:26 pm, Sean Swallow wrote:
> List,
>
> I just got a tyan tiger w/ the AMD Viper chipset on it. For some
> reason Linux will only set the onboard (AMD viper) chains to UDMA33.
>
> I'm using linux 2.4.9, and I have also tried 2.4.10. Is there a
> limitation to the AMD Viper driver?
>
> PS. The cables (2) are BRAND new ata100 cables.
>
> cheers,

Welcome to hell.
I belive the solution is to enable the option "IGNORE word93 Validation 
BITS" at the bottom of the "IDE, ATA and ATAPI Block Devices" menu 
accessable in "ATA/IDE/MFM/RLL support"

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

* Re: AMD viper chipset and UDMA100
  2001-09-27 21:26 AMD viper chipset and UDMA100 Sean Swallow
  2001-09-27 21:36 ` Nicholas Knight
@ 2001-09-27 21:59 ` Vojtech Pavlik
  2001-09-27 22:16   ` Dan Hollis
  1 sibling, 1 reply; 10+ messages in thread
From: Vojtech Pavlik @ 2001-09-27 21:59 UTC (permalink / raw)
  To: Sean Swallow; +Cc: linux-kernel

On Thu, Sep 27, 2001 at 02:26:50PM -0700, Sean Swallow wrote:
> List,
> 
> I just got a tyan tiger w/ the AMD Viper chipset on it. For some reason
> Linux will only set the onboard (AMD viper) chains to UDMA33.
> 
> I'm using linux 2.4.9, and I have also tried 2.4.10. Is there a limitation
> to the AMD Viper driver?
> 
> PS. The cables (2) are BRAND new ata100 cables.

The Viper can do UDMA66 max. At least it's doing it for me quite well.

-- 
Vojtech Pavlik
SuSE Labs

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

* Re: AMD viper chipset and UDMA100
  2001-09-27 21:59 ` Vojtech Pavlik
@ 2001-09-27 22:16   ` Dan Hollis
  2001-09-27 22:24     ` Vojtech Pavlik
  0 siblings, 1 reply; 10+ messages in thread
From: Dan Hollis @ 2001-09-27 22:16 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-kernel

On Thu, 27 Sep 2001, Vojtech Pavlik wrote:
> On Thu, Sep 27, 2001 at 02:26:50PM -0700, Sean Swallow wrote:
> > I just got a tyan tiger w/ the AMD Viper chipset on it. For some reason
> > Linux will only set the onboard (AMD viper) chains to UDMA33.
> > I'm using linux 2.4.9, and I have also tried 2.4.10. Is there a limitation
> > to the AMD Viper driver?
> > PS. The cables (2) are BRAND new ata100 cables.
> The Viper can do UDMA66 max. At least it's doing it for me quite well.

If he's got the Tyan Tiger i'm thinking of, it's the Tyan S2460 with
AMD766 southbridge. Tyan says it will do U100:
http://www.tyan.com/products/html/tigermp.html

AMD does too:
http://www.amd.com/us-en/Processors/TechnicalResources/0,,30_182_873,00.html

And I've got the same problem with my S2460:

Uniform Multi-Platform E-IDE driver Revision: 6.31
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
AMD7411: IDE controller on PCI bus 00 dev 39
AMD7411: chipset revision 1
AMD7411: not 100% native mode: will probe irqs later
AMD7411: disabling single-word DMA support (revision < C4)
    ide0: BM-DMA at 0xf000-0xf007, BIOS settings: hda:DMA, hdb:pio
    ide1: BM-DMA at 0xf008-0xf00f, BIOS settings: hdc:DMA, hdd:pio
hda: 20010816 sectors (10246 MB) w/2048KiB Cache, CHS=1245/255/63, UDMA(33)
hdc: 160086528 sectors (81964 MB) w/2048KiB Cache, CHS=158816/16/63, UDMA(33)

But these drives will do U66/U100:

# /sbin/hdparm -i /dev/hda

/dev/hda:

 Model=Maxtor 51024U2, FwRev=DA620CQ0, SerialNo=K203Z2WC
 Config={ Fixed }
 RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=57
 BuffType=3(DualPortCache), BuffSize=2048kB, MaxMultSect=16, MultSect=16
 DblWordIO=no, OldPIO=2, DMA=yes, OldDMA=0
 CurCHS=16383/16/63, CurSects=-66060037, LBA=yes, LBAsects=20010816
 tDMA={min:120,rec:120}, DMA modes: mword0 mword1 mword2
 IORDY=on/off, tPIO={min:120,w/IORDY:120}, PIO modes: mode3 mode4
 UDMA modes: mode0 mode1 *mode2 mode3 mode4

# /sbin/hdparm -i /dev/hdc

/dev/hdc:

 Model=Maxtor 98196H8, FwRev=ZAH814Y0, SerialNo=V803V81C
 Config={ Fixed }
 RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=57
 BuffType=3(DualPortCache), BuffSize=2048kB, MaxMultSect=16, MultSect=16
 DblWordIO=no, OldPIO=2, DMA=yes, OldDMA=0
 CurCHS=16383/16/63, CurSects=-66060037, LBA=yes, LBAsects=160086528
 tDMA={min:120,rec:120}, DMA modes: mword0 mword1 mword2
 IORDY=on/off, tPIO={min:120,w/IORDY:120}, PIO modes: mode3 mode4
 UDMA modes: mode0 mode1 *mode2 mode3 mode4 mode5

And yes, I *DO* have the proper cables. These same drives connected to a
Promise 20267 or a VIA KT133 with the same cables will do U66/U100
perfectly.

-Dan
-- 
[-] Omae no subete no kichi wa ore no mono da. [-]


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

* Re: AMD viper chipset and UDMA100
  2001-09-27 22:16   ` Dan Hollis
@ 2001-09-27 22:24     ` Vojtech Pavlik
  2001-09-27 22:54       ` Dan Hollis
  2001-09-27 23:37       ` Sean Swallow
  0 siblings, 2 replies; 10+ messages in thread
From: Vojtech Pavlik @ 2001-09-27 22:24 UTC (permalink / raw)
  To: Dan Hollis; +Cc: linux-kernel

On Thu, Sep 27, 2001 at 03:16:18PM -0700, Dan Hollis wrote:

> On Thu, 27 Sep 2001, Vojtech Pavlik wrote:
> > On Thu, Sep 27, 2001 at 02:26:50PM -0700, Sean Swallow wrote:
> > > I just got a tyan tiger w/ the AMD Viper chipset on it. For some reason
> > > Linux will only set the onboard (AMD viper) chains to UDMA33.
> > > I'm using linux 2.4.9, and I have also tried 2.4.10. Is there a limitation
> > > to the AMD Viper driver?
> > > PS. The cables (2) are BRAND new ata100 cables.
> > The Viper can do UDMA66 max. At least it's doing it for me quite well.
> 
> If he's got the Tyan Tiger i'm thinking of, it's the Tyan S2460 with
> AMD766 southbridge. Tyan says it will do U100:
> http://www.tyan.com/products/html/tigermp.html

This southbridge is called Viper Plus as far as I know. In the past,
I've written a driver for this, but it didn't make it into the kernel,
because Andre also had his version.

> AMD does too:
> http://www.amd.com/us-en/Processors/TechnicalResources/0,,30_182_873,00.html
> 
> And I've got the same problem with my S2460:
> 
> Uniform Multi-Platform E-IDE driver Revision: 6.31
> ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
> AMD7411: IDE controller on PCI bus 00 dev 39
> AMD7411: chipset revision 1
> AMD7411: not 100% native mode: will probe irqs later
> AMD7411: disabling single-word DMA support (revision < C4)
>     ide0: BM-DMA at 0xf000-0xf007, BIOS settings: hda:DMA, hdb:pio
>     ide1: BM-DMA at 0xf008-0xf00f, BIOS settings: hdc:DMA, hdd:pio
> hda: 20010816 sectors (10246 MB) w/2048KiB Cache, CHS=1245/255/63, UDMA(33)
> hdc: 160086528 sectors (81964 MB) w/2048KiB Cache, CHS=158816/16/63, UDMA(33)
> 
> But these drives will do U66/U100:
> 
> And yes, I *DO* have the proper cables. These same drives connected to a
> Promise 20267 or a VIA KT133 with the same cables will do U66/U100
> perfectly.

Perhaps I could dig up my code and you can give it a test. Would you be
interested?

-- 
Vojtech Pavlik
SuSE Labs

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

* Re: AMD viper chipset and UDMA100
  2001-09-27 22:24     ` Vojtech Pavlik
@ 2001-09-27 22:54       ` Dan Hollis
  2001-09-28  2:21         ` Jacob Luna Lundberg
  2001-09-27 23:37       ` Sean Swallow
  1 sibling, 1 reply; 10+ messages in thread
From: Dan Hollis @ 2001-09-27 22:54 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-kernel

On Fri, 28 Sep 2001, Vojtech Pavlik wrote:
> This southbridge is called Viper Plus as far as I know. In the past,
> I've written a driver for this, but it didn't make it into the kernel,
> because Andre also had his version.

And Andre's didnt make it into the kernel either it seems :-)

> Perhaps I could dig up my code and you can give it a test. Would you be
> interested?

Sure.

-Dan
-- 
[-] Omae no subete no kichi wa ore no mono da. [-]


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

* Re: AMD viper chipset and UDMA100
  2001-09-27 22:24     ` Vojtech Pavlik
  2001-09-27 22:54       ` Dan Hollis
@ 2001-09-27 23:37       ` Sean Swallow
  2001-09-28 10:21         ` [patch] " Vojtech Pavlik
  1 sibling, 1 reply; 10+ messages in thread
From: Sean Swallow @ 2001-09-27 23:37 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Dan Hollis, linux-kernel

Vojtech,

I would be interested in trying out your code.

cheers,

-- 
Sean J. Swallow
pgp (6.5.2) keyfile @ https://nurk.org/keyfile.txt


On Fri, 28 Sep 2001, Vojtech Pavlik wrote:

> On Thu, Sep 27, 2001 at 03:16:18PM -0700, Dan Hollis wrote:
>
> > On Thu, 27 Sep 2001, Vojtech Pavlik wrote:
> > > On Thu, Sep 27, 2001 at 02:26:50PM -0700, Sean Swallow wrote:
> > > > I just got a tyan tiger w/ the AMD Viper chipset on it. For some reason
> > > > Linux will only set the onboard (AMD viper) chains to UDMA33.
> > > > I'm using linux 2.4.9, and I have also tried 2.4.10. Is there a limitation
> > > > to the AMD Viper driver?
> > > > PS. The cables (2) are BRAND new ata100 cables.
> > > The Viper can do UDMA66 max. At least it's doing it for me quite well.
> >
> > If he's got the Tyan Tiger i'm thinking of, it's the Tyan S2460 with
> > AMD766 southbridge. Tyan says it will do U100:
> > http://www.tyan.com/products/html/tigermp.html
>
> This southbridge is called Viper Plus as far as I know. In the past,
> I've written a driver for this, but it didn't make it into the kernel,
> because Andre also had his version.
>
> > AMD does too:
> > http://www.amd.com/us-en/Processors/TechnicalResources/0,,30_182_873,00.html
> >
> > And I've got the same problem with my S2460:
> >
> > Uniform Multi-Platform E-IDE driver Revision: 6.31
> > ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
> > AMD7411: IDE controller on PCI bus 00 dev 39
> > AMD7411: chipset revision 1
> > AMD7411: not 100% native mode: will probe irqs later
> > AMD7411: disabling single-word DMA support (revision < C4)
> >     ide0: BM-DMA at 0xf000-0xf007, BIOS settings: hda:DMA, hdb:pio
> >     ide1: BM-DMA at 0xf008-0xf00f, BIOS settings: hdc:DMA, hdd:pio
> > hda: 20010816 sectors (10246 MB) w/2048KiB Cache, CHS=1245/255/63, UDMA(33)
> > hdc: 160086528 sectors (81964 MB) w/2048KiB Cache, CHS=158816/16/63, UDMA(33)
> >
> > But these drives will do U66/U100:
> >
> > And yes, I *DO* have the proper cables. These same drives connected to a
> > Promise 20267 or a VIA KT133 with the same cables will do U66/U100
> > perfectly.
>
> Perhaps I could dig up my code and you can give it a test. Would you be
> interested?
>
>


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

* Re: AMD viper chipset and UDMA100
  2001-09-27 22:54       ` Dan Hollis
@ 2001-09-28  2:21         ` Jacob Luna Lundberg
  0 siblings, 0 replies; 10+ messages in thread
From: Jacob Luna Lundberg @ 2001-09-28  2:21 UTC (permalink / raw)
  To: Dan Hollis; +Cc: Vojtech Pavlik, linux-kernel


On Thu, 27 Sep 2001, Dan Hollis wrote:
> And Andre's didnt make it into the kernel either it seems :-)

He hasn't even been updating his patch with taskfile and destroke support
in it for recent kernels, sadly (sadly because I need destroke).  However,
I've been trying to bring it forward myself; you can find it at:
http://chaos2.org/~jacob/code/linux/

I don't know if it's got anything useful to you in it, particularly given
that there are items like the two below which seem to be help chunks for
things that have recently made it into the kernel (without help, heh):


-AMD7409 chipset support
-CONFIG_BLK_DEV_AMD7409
-  This driver ensures (U)DMA support for the AMD756 Viper chipset.
+AMD Viper (7401/7409/7411) chipset support
+CONFIG_BLK_DEV_AMD74XX
+  This driver ensures (U)DMA support for the AMD756/760 Viper chipset.

[and]

-CONFIG_AMD7409_OVERRIDE
+CONFIG_AMD74XX_OVERRIDE


At any rate, I don't know if it's applicable for your problems at all
(it's not a small patch) but you're welcome to a copy of it if you want.

-Jacob


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

* [patch] Re: AMD viper chipset and UDMA100
  2001-09-27 23:37       ` Sean Swallow
@ 2001-09-28 10:21         ` Vojtech Pavlik
  0 siblings, 0 replies; 10+ messages in thread
From: Vojtech Pavlik @ 2001-09-28 10:21 UTC (permalink / raw)
  To: Sean Swallow; +Cc: Dan Hollis, linux-kernel, Jacob Luna Lundberg

[-- Attachment #1: Type: text/plain, Size: 367 bytes --]

On Thu, Sep 27, 2001 at 04:37:50PM -0700, Sean Swallow wrote:

> Vojtech,
> 
> I would be interested in trying out your code.

Ok. It should make your ViperPlus work with UDMA100. The patch is
against 2.4.10, but will probably work with any similar kernel. It
completely replaces Andre's driver with mine. Find it attached.

Good luck. 

-- 
Vojtech Pavlik
SuSE Labs

[-- Attachment #2: viper-vojtech.diff --]
[-- Type: text/plain, Size: 28266 bytes --]

diff -urN linux-2.4.10/drivers/ide/amd74xx.c linux/drivers/ide/amd74xx.c
--- linux-2.4.10/drivers/ide/amd74xx.c	Mon Aug 13 23:56:19 2001
+++ linux/drivers/ide/amd74xx.c	Fri Sep 28 12:07:50 2001
@@ -1,485 +1,431 @@
 /*
- * linux/drivers/ide/amd74xx.c		Version 0.05	June 9, 2000
+ * $Id: amd74xx.c,v 2.5 2001/09/28 11:44:00 vojtech Exp $
  *
- * Copyright (C) 1999-2000		Andre Hedrick <andre@linux-ide.org>
- * May be copied or modified under the terms of the GNU General Public License
+ *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
+ *  Based on the work of:
+ *	Andre Hedrick
+ */
+
+/*
+ * AMD 755/756/766 IDE driver for Linux.
+ *
+ * UDMA66 and higher modes are autoenabled only in case the BIOS has detected a
+ * 80 wire cable. To ignore the BIOS data and assume the cable is present, use
+ * 'ide0=ata66' or 'ide1=ata66' on the kernel command line.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
 #include <linux/config.h>
-#include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/blkdev.h>
-#include <linux/hdreg.h>
-
-#include <linux/interrupt.h>
-#include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 #include <linux/ide.h>
-
 #include <asm/io.h>
-#include <asm/irq.h>
 
-#include "ide_modes.h"
+#include "ide-timing.h"
 
-#define DISPLAY_VIPER_TIMINGS
+#define AMD_IDE_ENABLE		0x40
+#define AMD_IDE_CONFIG		0x41
+#define AMD_CABLE_DETECT	0x42
+#define AMD_DRIVE_TIMING	0x48
+#define AMD_8BIT_TIMING		0x4e
+#define AMD_ADDRESS_SETUP	0x4c
+#define AMD_UDMA_TIMING		0x50
+
+#define AMD_UDMA		0x07
+#define AMD_UDMA_33		0x01
+#define AMD_UDMA_66		0x02
+#define AMD_UDMA_100		0x03
+#define AMD_BAD_SWDMA		0x08
+#define AMD_BAD_FIFO		0x10
+
+/*
+ * AMD SouthBridge chips.
+ */
+
+static struct amd_ide_chip {
+	char *name;
+	unsigned short id;
+	unsigned char rev;
+	unsigned char flags;
+} amd_ide_chips[] = {
+	{ "766 ViperPlus",	PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, AMD_UDMA_100 | AMD_BAD_FIFO },
+	{ "756/c4+ Viper",	PCI_DEVICE_ID_AMD_VIPER_7409, 0x07, AMD_UDMA_66 },
+	{ "756 Viper",		PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, AMD_UDMA_66 | AMD_BAD_SWDMA },
+	{ "755 Cobra",		PCI_DEVICE_ID_AMD_COBRA_7401, 0x00, AMD_UDMA_33 | AMD_BAD_SWDMA },
+	{ NULL }
+};
+
+static struct amd_ide_chip *amd_config;
+static unsigned char amd_enabled;
+static unsigned int amd_80w;
+static unsigned int amd_clock;
+
+static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3 };
+static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 1 };
+static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100" };
+
+/*
+ * AMD /proc entry.
+ */
+
+#ifdef CONFIG_PROC_FS
 
-#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 
-static int amd74xx_get_info(char *, char **, off_t, int);
-extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
-extern char *ide_media_verbose(ide_drive_t *);
+byte amd74xx_proc;
+int amd_base;
 static struct pci_dev *bmide_dev;
+extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
 
-static int amd74xx_get_info (char *buffer, char **addr, off_t offset, int count)
-{
+#define amd_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
+#define amd_print_drive(name, format, arg...)\
+	p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
+
+static int amd_get_info(char *buffer, char **addr, off_t offset, int count)
+{
+	short speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
+		 uen[4], udma[4], active8b[4], recover8b[4];
+	struct pci_dev *dev = bmide_dev;
+	unsigned int v, u, i;
+	unsigned short c, w;
+	unsigned char t;
 	char *p = buffer;
-	u32 bibma = pci_resource_start(bmide_dev, 4);
-	u8 c0 = 0, c1 = 0;
 
-	/*
-	 * at that point bibma+0x2 et bibma+0xa are byte registers
-	 * to investigate:
-	 */
-	c0 = inb_p((unsigned short)bibma + 0x02);
-	c1 = inb_p((unsigned short)bibma + 0x0a);
-
-	p += sprintf(p, "\n                                AMD %04X VIPER Chipset.\n", bmide_dev->device);
-	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
-	p += sprintf(p, "                %sabled                         %sabled\n",
-			(c0&0x80) ? "dis" : " en",
-			(c1&0x80) ? "dis" : " en");
-	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
-			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
-			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
-	p += sprintf(p, "UDMA\n");
-	p += sprintf(p, "DMA\n");
-	p += sprintf(p, "PIO\n");
+	amd_print("----------AMD BusMastering IDE Configuration----------------");
 
-	return p-buffer;	/* => must be less than 4k! */
-}
-#endif  /* defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) */
+	amd_print("Driver Version:                     2.5");
+	amd_print("South Bridge:                       AMD-%s", amd_config->name);
 
-byte amd74xx_proc = 0;
+	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
+	amd_print("Revision:                           IDE %#x", t);
+	amd_print("Highest DMA rate:                   %s", amd_dma[amd_config->flags & AMD_UDMA]);
 
-extern char *ide_xfer_verbose (byte xfer_rate);
+	amd_print("BM-DMA base:                        %#x", amd_base);
+	amd_print("PCI clock:                          %dMHz", amd_clock);
+	
+	amd_print("-----------------------Primary IDE-------Secondary IDE------");
 
-static unsigned int amd74xx_swdma_check (struct pci_dev *dev)
-{
-	unsigned int class_rev;
+	pci_read_config_byte(dev, AMD_IDE_CONFIG, &t);
+	amd_print("Prefetch Buffer:       %10s%20s", (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no");
+	amd_print("Post Write Buffer:     %10s%20s", (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
 
-	if (dev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
-		return 0;
+	pci_read_config_byte(dev, AMD_IDE_ENABLE, &t);
+	amd_print("Enabled:               %10s%20s", (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no");
 
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xff;
-	return ((int) (class_rev >= 7) ? 1 : 0);
-}
+	c = inb(amd_base + 0x02) | (inb(amd_base + 0x0a) << 8);
+	amd_print("Simplex only:          %10s%20s", (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
 
-static int amd74xx_swdma_error(ide_drive_t *drive)
-{
-	printk("%s: single-word DMA not support (revision < C4)\n", drive->name);
-	return 0;
-}
+	amd_print("Cable Type:            %10s%20s", (amd_80w & 1) ? "80w" : "40w", (amd_80w & 2) ? "80w" : "40w");
 
-/*
- * Here is where all the hard work goes to program the chipset.
- *
- */
-static int amd74xx_tune_chipset (ide_drive_t *drive, byte speed)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	int err			= 0;
-	byte unit		= (drive->select.b.unit & 0x01);
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	unsigned long dma_base	= hwif->dma_base;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-	byte drive_pci		= 0x00;
-	byte drive_pci2		= 0x00;
-	byte ultra_timing	= 0x00;
-	byte dma_pio_timing	= 0x00;
-	byte pio_timing		= 0x00;
-
-        switch (drive->dn) {
-		case 0: drive_pci = 0x53; drive_pci2 = 0x4b; break;
-		case 1: drive_pci = 0x52; drive_pci2 = 0x4a; break;
-		case 2: drive_pci = 0x51; drive_pci2 = 0x49; break;
-		case 3: drive_pci = 0x50; drive_pci2 = 0x48; break;
-		default:
-                        return -1;
-        }
-
-	pci_read_config_byte(dev, drive_pci, &ultra_timing);
-	pci_read_config_byte(dev, drive_pci2, &dma_pio_timing);
-	pci_read_config_byte(dev, 0x4c, &pio_timing);
-
-#ifdef DEBUG
-	printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
-		drive->name, ultra_timing, dma_pio_timing, pio_timing);
-#endif
+	if (!amd_clock)
+                return p - buffer;
 
-	ultra_timing	&= ~0xC7;
-	dma_pio_timing	&= ~0xFF;
-	pio_timing	&= ~(0x03 << drive->dn);
-
-#ifdef DEBUG
-	printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
-		ultra_timing, dma_pio_timing, pio_timing);
-#endif
+	amd_print("-------------------drive0----drive1----drive2----drive3-----");
 
-	switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
-		case XFER_UDMA_5:
-#undef __CAN_MODE_5
-#ifdef __CAN_MODE_5
-			ultra_timing |= 0x46;
-			dma_pio_timing |= 0x20;
-			break;
-#else
-			printk("%s: setting to mode 4, driver problems in mode 5.\n", drive->name);
-			speed = XFER_UDMA_4;
-#endif /* __CAN_MODE_5 */
-		case XFER_UDMA_4:
-			ultra_timing |= 0x45;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_3:
-			ultra_timing |= 0x44;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_2:
-			ultra_timing |= 0x40;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_1:
-			ultra_timing |= 0x41;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_UDMA_0:
-			ultra_timing |= 0x42;
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_MW_DMA_2:
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_MW_DMA_1:
-			dma_pio_timing |= 0x21;
-			break;
-		case XFER_MW_DMA_0:
-			dma_pio_timing |= 0x77;
-			break;
-		case XFER_SW_DMA_2:
-			if (!amd74xx_swdma_check(dev))
-				return amd74xx_swdma_error(drive);
-			dma_pio_timing |= 0x42;
-			break;
-		case XFER_SW_DMA_1:
-			if (!amd74xx_swdma_check(dev))
-				return amd74xx_swdma_error(drive);
-			dma_pio_timing |= 0x65;
-			break;
-		case XFER_SW_DMA_0:
-			if (!amd74xx_swdma_check(dev))
-				return amd74xx_swdma_error(drive);
-			dma_pio_timing |= 0xA8;
-			break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-		case XFER_PIO_4:
-			dma_pio_timing |= 0x20;
-			break;
-		case XFER_PIO_3:
-			dma_pio_timing |= 0x22;
-			break;
-		case XFER_PIO_2:
-			dma_pio_timing |= 0x42;
-			break;
-		case XFER_PIO_1:
-			dma_pio_timing |= 0x65;
-			break;
-		case XFER_PIO_0:
-		default:
-			dma_pio_timing |= 0xA8;
-			break;
-        }
+	pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t);
+	pci_read_config_dword(dev, AMD_DRIVE_TIMING, &v);
+	pci_read_config_word(dev, AMD_8BIT_TIMING, &w);
+	pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
 
-	pio_timing |= (0x03 << drive->dn);
+	for (i = 0; i < 4; i++) {
+		setup[i]     = ((t >> ((3 - i) << 1)) & 0x3) + 1;
+		recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1;
+		active8b[i]  = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1;
+		active[i]    = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1;
+		recover[i]   = ((v >> ((3 - i) << 3)) & 0xf) + 1;
 
-	if (!drive->init_speed)
-		drive->init_speed = speed;
+		udma[i] = amd_udma2cyc[((u >> ((3 - i) << 3)) & 0x7)];
+		uen[i]  = ((u >> ((3 - i) << 3)) & 0x40) ? 1 : 0;
+		den[i]  = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	pci_write_config_byte(dev, drive_pci, ultra_timing);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-	pci_write_config_byte(dev, drive_pci2, dma_pio_timing);
-	pci_write_config_byte(dev, 0x4c, pio_timing);
+		if (den[i] && uen[i] && udma[i] == 1) {
+			speed[i] = amd_clock * 30;
+			cycle[i] = 666 / amd_clock;
+			continue;
+		}
+
+		speed[i] = 40 * amd_clock / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2);
+		cycle[i] = 1000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / amd_clock / 2;
+	}
+
+	amd_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
+
+	amd_print_drive("Address Setup: ", "%8dns", 1000 * setup[i] / amd_clock);
+	amd_print_drive("Cmd Active:    ", "%8dns", 1000 * active8b[i] / amd_clock);
+	amd_print_drive("Cmd Recovery:  ", "%8dns", 1000 * recover8b[i] / amd_clock);
+	amd_print_drive("Data Active:   ", "%8dns", 1000 * active[i] / amd_clock);
+	amd_print_drive("Data Recovery: ", "%8dns", 1000 * recover[i] / amd_clock);
+	amd_print_drive("Cycle Time:    ", "%8dns", cycle[i]);
+	amd_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 10, speed[i] % 10);
+
+	return p - buffer;	/* hoping it is less than 4K... */
+}
 
-#ifdef DEBUG
-	printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
-		ultra_timing, dma_pio_timing, pio_timing);
 #endif
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	if (speed > XFER_PIO_4) {
-		outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
-	} else {
-		outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+/*
+ * amd_set_speed() writes timing values to the chipset registers
+ */
+
+static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timing *timing)
+{
+	unsigned char t;
+
+	pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t);
+	t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
+	pci_write_config_byte(dev, AMD_ADDRESS_SETUP, t);
+
+	pci_write_config_byte(dev, AMD_8BIT_TIMING + (1 - (dn >> 1)),
+		((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1));
+
+	pci_write_config_byte(dev, AMD_DRIVE_TIMING + (3 - dn),
+		((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
+
+	switch (amd_config->flags & AMD_UDMA) {
+		case AMD_UDMA_33:  t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
+		case AMD_UDMA_66:  t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break;
+		case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break;
+		default: return;
 	}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
 
-	err = ide_config_drive_speed(drive, speed);
-	drive->current_speed = speed;
-	return (err);
+	pci_write_config_byte(dev, AMD_UDMA_TIMING + (3 - dn), t);
 }
 
-static void config_chipset_for_pio (ide_drive_t *drive)
+/*
+ * amd_set_drive() computes timing values configures the drive and
+ * the chipset to a desired transfer mode. It also can be called
+ * by upper layers.
+ */
+
+static int amd_set_drive(ide_drive_t *drive, unsigned char speed)
 {
-	unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-	unsigned short xfer_pio	= drive->id->eide_pio_modes;
-	byte			timing, speed, pio;
-
-	pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
-
-	if (xfer_pio> 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0) {
-		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-			xfer_pio--);
-	} else {
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 :
-			   (drive->id->tPIO & 2) ? 0x02 :
-			   (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
-	}
+	ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
+	struct ide_timing t, p;
+	int T, UT;
 
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
+	if (speed != XFER_PIO_SLOW && speed != drive->current_speed)
+		if (ide_config_drive_speed(drive, speed))
+			printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n",
+				drive->dn >> 1, drive->dn & 1);
 
-	switch(timing) {
-		case 4: speed = XFER_PIO_4;break;
-		case 3: speed = XFER_PIO_3;break;
-		case 2: speed = XFER_PIO_2;break;
-		case 1: speed = XFER_PIO_1;break;
-		default:
-			speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-			break;
+	T = 1000 / amd_clock;
+	UT = T / MIN(MAX(amd_config->flags & AMD_UDMA, 1), 2);
+
+	ide_timing_compute(drive, speed, &t, T, UT);
+
+	if (peer->present) {
+		ide_timing_compute(peer, peer->current_speed, &p, T, UT);
+		ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
 	}
-	(void) amd74xx_tune_chipset(drive, speed);
+
+	if (speed == XFER_UDMA_5 && amd_clock <= 33) t.udma = 1;
+
+	amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
+
+	if (!drive->init_speed)	
+		drive->init_speed = speed;
 	drive->current_speed = speed;
+
+	return 0;
 }
 
-static void amd74xx_tune_drive (ide_drive_t *drive, byte pio)
+/*
+ * amd74xx_tune_drive() is a callback from upper layers for
+ * PIO-only tuning.
+ */
+
+static void amd74xx_tune_drive(ide_drive_t *drive, unsigned char pio)
 {
-	byte speed;
-	switch(pio) {
-		case 4:		speed = XFER_PIO_4;break;
-		case 3:		speed = XFER_PIO_3;break;
-		case 2:		speed = XFER_PIO_2;break;
-		case 1:		speed = XFER_PIO_1;break;
-		default:	speed = XFER_PIO_0;break;
+	if (!((amd_enabled >> HWIF(drive)->channel) & 1))
+		return;
+
+	if (pio == 255) {
+		amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
+		return;
 	}
-	(void) amd74xx_tune_chipset(drive, speed);
+
+	amd_set_drive(drive, XFER_PIO_0 + MIN(pio, 5));
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
+
 /*
- * This allows the configuration of ide_pci chipset registers
- * for cards that learn about the drive's UDMA, DMA, PIO capabilities
- * after the drive is reported by the OS.
+ * amd74xx_dmaproc() is a callback from upper layers that can do
+ * a lot, but we use it for DMA/PIO tuning only, delegating everything
+ * else to the default ide_dmaproc().
  */
-static int config_chipset_for_dma (ide_drive_t *drive)
+
+int amd74xx_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	struct hd_driveid *id	= drive->id;
-	byte udma_66		= eighty_ninty_three(drive);
-	byte udma_100		= (dev->device==PCI_DEVICE_ID_AMD_VIPER_7411) ? 1 : 0;
-	byte speed		= 0x00;
-	int  rval;
-
-	if ((id->dma_ultra & 0x0020) && (udma_66)&& (udma_100)) {
-		speed = XFER_UDMA_5;
-	} else if ((id->dma_ultra & 0x0010) && (udma_66)) {
-		speed = XFER_UDMA_4;
-	} else if ((id->dma_ultra & 0x0008) && (udma_66)) {
-		speed = XFER_UDMA_3;
-	} else if (id->dma_ultra & 0x0004) {
-		speed = XFER_UDMA_2;
-	} else if (id->dma_ultra & 0x0002) {
-		speed = XFER_UDMA_1;
-	} else if (id->dma_ultra & 0x0001) {
-		speed = XFER_UDMA_0;
-	} else if (id->dma_mword & 0x0004) {
-		speed = XFER_MW_DMA_2;
-	} else if (id->dma_mword & 0x0002) {
-		speed = XFER_MW_DMA_1;
-	} else if (id->dma_mword & 0x0001) {
-		speed = XFER_MW_DMA_0;
-	} else {
-		return ((int) ide_dma_off_quietly);
-	}
 
-	(void) amd74xx_tune_chipset(drive, speed);
+	if (func == ide_dma_check) {
 
-	rval = (int)(	((id->dma_ultra >> 11) & 3) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+		short w80 = HWIF(drive)->udma_four;
 
-	return rval;
+		short speed = ide_find_best_mode(drive,
+			XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA |
+			((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
+			(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
+			(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0));
+
+		amd_set_drive(drive, speed);
+
+		func = (HWIF(drive)->autodma && (speed & XFER_MODE) != XFER_PIO)
+			? ide_dma_on : ide_dma_off_quietly;
+	}
+
+	return ide_dmaproc(func, drive);
 }
 
-static int config_drive_xfer_rate (ide_drive_t *drive)
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+/*
+ * The initialization callback. Here we determine the IDE chip type
+ * and initialize its drive independent registers.
+ */
+
+unsigned int __init pci_init_amd74xx(struct pci_dev *dev, const char *name)
 {
-	struct hd_driveid *id = drive->id;
-	ide_dma_action_t dma_func = ide_dma_on;
+	unsigned char t;
+	unsigned int u;
+	int i;
 
-	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
-		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
-			dma_func = ide_dma_off;
-			goto fast_ata_pio;
-		}
-		dma_func = ide_dma_off_quietly;
-		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x002F) {
-				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive);
-				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
-					goto try_dma_modes;
-			}
-		} else if (id->field_valid & 2) {
-try_dma_modes:
-			if ((id->dma_mword & 0x0007) ||
-			    ((id->dma_1word & 0x007) &&
-			     (amd74xx_swdma_check(HWIF(drive)->pci_dev)))) {
-				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive);
-				if (dma_func != ide_dma_on)
-					goto no_dma_set;
-			}
-			
-		} else if (ide_dmaproc(ide_dma_good_drive, drive)) {
-			if (id->eide_dma_time > 150) {
-				goto no_dma_set;
-			}
-			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive);
-			if (dma_func != ide_dma_on)
-				goto no_dma_set;
-		} else {
-			goto fast_ata_pio;
+/*
+ * Find out what AMD IDE is this.
+ */
+
+	for (amd_config = amd_ide_chips; amd_config->id; amd_config++) {
+			pci_read_config_byte(dev, PCI_REVISION_ID, &t);
+			if (dev->device == amd_config->id && t >= amd_config->rev)
+				break;
 		}
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
-no_dma_set:
 
-		config_chipset_for_pio(drive);
+	if (!amd_config->id) {
+		printk(KERN_WARNING "AMD74xx: Unknown AMD IDE Chip, contact Vojtech Pavlik <vojtech@ucw.cz>\n");
+		return -ENODEV;
 	}
-	return HWIF(drive)->dmaproc(dma_func, drive);
-}
 
 /*
- * amd74xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
+ * Check 80-wire cable presence.
  */
 
-int amd74xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
-{
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		default:
+	switch (amd_config->flags & AMD_UDMA) {
+
+		case AMD_UDMA_100:
+			pci_read_config_byte(dev, AMD_CABLE_DETECT, &t);
+			amd_80w = ((u & 0x3) ? 1 : 0) | ((u & 0xc) ? 2 : 0);
+			for (i = 24; i >= 0; i -= 8)
+				if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) {
+					printk(KERN_WARNING "AMD74xx: Bios didn't set cable bits corectly. Enabling workaround.\n");
+					amd_80w |= (1 << (1 - (i >> 4)));
+				}
+			break;
+
+		case AMD_UDMA_66:
+			pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
+			for (i = 24; i >= 0; i -= 8)
+				if ((u >> i) & 4)
+					amd_80w |= (1 << (1 - (i >> 4)));
 			break;
 	}
-	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
-}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
 
-unsigned int __init pci_init_amd74xx (struct pci_dev *dev, const char *name)
-{
-	unsigned long fixdma_base = pci_resource_start(dev, 4);
+	pci_read_config_dword(dev, AMD_IDE_ENABLE, &u);
+	amd_enabled = ((u & 1) ? 2 : 0) | ((u & 2) ? 1 : 0);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	if (!amd74xx_swdma_check(dev))
-		printk("%s: disabling single-word DMA support (revision < C4)\n", name);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+/*
+ * Take care of prefetch & postwrite.
+ */
 
-	if (!fixdma_base) {
-		/*
-		 *
-		 */
-	} else {
-		/*
-		 * enable DMA capable bit, and "not" simplex only
-		 */
-		outb(inb(fixdma_base+2) & 0x60, fixdma_base+2);
+	pci_read_config_byte(dev, AMD_IDE_CONFIG, &t);
+	pci_write_config_byte(dev, AMD_IDE_CONFIG,
+		(amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0));
 
-		if (inb(fixdma_base+2) & 0x80)
-			printk("%s: simplex device: DMA will fail!!\n", name);
-	}
-#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
+/*
+ * Print the boot message.
+ */
+
+	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
+	printk(KERN_INFO "AMD74xx: AMD-%s (rev %02x) IDE %s controller on pci%s\n",
+			amd_config->name, t, amd_dma[amd_config->flags & AMD_UDMA], dev->slot_name);
+
+/*
+ * Register /proc/ide/amd74xx entry
+ */
+
+#ifdef CONFIG_PROC_FS
 	if (!amd74xx_proc) {
-		amd74xx_proc = 1;
+		amd_base = pci_resource_start(dev, 4);
 		bmide_dev = dev;
-		amd74xx_display_info = &amd74xx_get_info;
+		amd74xx_display_info = &amd_get_info;
+		amd74xx_proc = 1;
+
 	}
-#endif /* DISPLAY_VIPER_TIMINGS && CONFIG_PROC_FS */
+#endif
 
 	return 0;
 }
 
-unsigned int __init ata66_amd74xx (ide_hwif_t *hwif)
+unsigned int __init ata66_amd74xx(ide_hwif_t *hwif)
 {
-#ifdef CONFIG_AMD74XX_OVERRIDE
-	byte ata66 = 1;
-#else
-	byte ata66 = 0;
-#endif /* CONFIG_AMD74XX_OVERRIDE */
-
-#if 0
-	pci_read_config_byte(hwif->pci_dev, 0x48, &ata66);
-	return ((ata66 & 0x02) ? 0 : 1);
-#endif
-	return ata66;
+	return ((amd_enabled & amd_80w) >> hwif->channel) & 1;
 }
 
-void __init ide_init_amd74xx (ide_hwif_t *hwif)
+void __init ide_init_amd74xx(ide_hwif_t *hwif)
 {
-	hwif->tuneproc = &amd74xx_tune_drive;
-	hwif->speedproc = &amd74xx_tune_chipset;
+	int i;
 
-#ifndef CONFIG_BLK_DEV_IDEDMA
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
+	hwif->tuneproc = &amd74xx_tune_drive;
+	hwif->speedproc = &amd_set_drive;
 	hwif->autodma = 0;
-	return;
-#else
 
+	for (i = 0; i < 2; i++) {
+		hwif->drives[i].io_32bit = 1;
+		hwif->drives[i].unmask = 1;
+		hwif->drives[i].autotune = 1;
+		hwif->drives[i].dn = hwif->channel * 2 + i;
+	}
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
 		hwif->dmaproc = &amd74xx_dmaproc;
+#ifdef CONFIG_IDEDMA_AUTO
 		if (!noautodma)
 			hwif->autodma = 1;
-	} else {
-		hwif->autodma = 0;
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+#endif
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
 
-void __init ide_dmacapable_amd74xx (ide_hwif_t *hwif, unsigned long dmabase)
+/*
+ * We allow the BM-DMA driver only work on enabled interfaces.
+ */
+
+void __init ide_dmacapable_amd74xx(ide_hwif_t *hwif, unsigned long dmabase)
 {
-	ide_setup_dma(hwif, dmabase, 8);
+	if ((amd_enabled >> hwif->channel) & 1)
+		ide_setup_dma(hwif, dmabase, 8);
 }
diff -urN linux-2.4.10/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- linux-2.4.10/drivers/ide/ide-pci.c	Sun Sep  9 19:43:02 2001
+++ linux/drivers/ide/ide-pci.c	Fri Sep 28 12:11:22 2001
@@ -432,14 +432,14 @@
 	{DEVID_CY82C693,"CY82C693",	PCI_CY82C693,	NULL,		INIT_CY82C693,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_HINT,	"HINT_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_CS5530,	"CS5530",	PCI_CS5530,	NULL,		INIT_CS5530,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_AMD7401,	"AMD7401",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
+	{DEVID_AMD7401,	"AMD7401",	PCI_AMD74XX,	ATA66_AMD74XX,	INIT_AMD74XX,	DMA_AMD74XX,	{{0x40,0x01,0x01}, {0x40,0x02,0x02}},	ON_BOARD,	0 },
 	{DEVID_AMD7409,	"AMD7409",	PCI_AMD74XX,	ATA66_AMD74XX,	INIT_AMD74XX,	DMA_AMD74XX,	{{0x40,0x01,0x01}, {0x40,0x02,0x02}},	ON_BOARD,	0 },
 	{DEVID_AMD7411,	"AMD7411",	PCI_AMD74XX,	ATA66_AMD74XX,	INIT_AMD74XX,	DMA_AMD74XX,	{{0x40,0x01,0x01}, {0x40,0x02,0x02}},	ON_BOARD,	0 },
 	{DEVID_PDCADMA,	"PDCADMA",	PCI_PDCADMA,	ATA66_PDCADMA,	INIT_PDCADMA,	DMA_PDCADMA,	{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
 	{DEVID_SLC90E66,"SLC90E66",	PCI_SLC90E66,	ATA66_SLC90E66,	INIT_SLC90E66,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
-        {DEVID_OSB4,    "ServerWorks OSB4",		PCI_SVWKS,	ATA66_SVWKS,	INIT_SVWKS,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_CSB5,	"ServerWorks CSB5",		PCI_SVWKS,	ATA66_SVWKS,	INIT_SVWKS,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
-	{DEVID_ITE8172G,"IT8172G",	PCI_IT8172,	NULL,	INIT_IT8172,	NULL,		{{0x00,0x00,0x00}, {0x40,0x00,0x01}},	ON_BOARD,	0 },
+        {DEVID_OSB4,    "ServerWorks OSB4", PCI_SVWKS,	ATA66_SVWKS,	INIT_SVWKS,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
+	{DEVID_CSB5,	"ServerWorks CSB5", PCI_SVWKS,	ATA66_SVWKS,	INIT_SVWKS,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
+	{DEVID_ITE8172G,"IT8172G",	PCI_IT8172,	NULL,		INIT_IT8172,	NULL,		{{0x00,0x00,0x00}, {0x40,0x00,0x01}},	ON_BOARD,	0 },
 	{IDE_PCI_DEVID_NULL, "PCI_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 }};
 
 /*

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

* Re: [patch] Re: AMD viper chipset and UDMA100
@ 2001-10-05 21:26 Steven Newbury
  0 siblings, 0 replies; 10+ messages in thread
From: Steven Newbury @ 2001-10-05 21:26 UTC (permalink / raw)
  To: linux-kernel; +Cc: vojtech

On Sep 28, 2001 at 10:21:14, Vojetch Pavlik wrote:
>
> On Thu, Sep 27, 2001 at 04:37:50PM -0700, Sean
Swallow wrote:
> 
> > Vojtech,
> > I would be interested in trying out your code.
>
> Ok. It should make your ViperPlus work with UDMA100.
> The patch is
> against 2.4.10, but will probably work with any
similar kernel. It
> completely replaces Andre's driver with mine. Find
it > attached.
> 
> Good luck. 
[patch snipped]
I have a Tyan K7 Thunder and I have tried this patch
and the patch from Andre, synced with 2.4.10 by Jacob
Luna and have had the same problem with both.  Without
the patch I can only do UDMA33 but the hw supports
UDMA100.  I have a Quantum FireballPlus AS40 on my
primary IDE channel which I have tested on an MSI
K7Master and works fine in UDMA100.

When I reboot with the driver enabled, as soon as hda
is detected the kernel locks up with a DIVIDE (0)
error.  I will try it again and take notes of more
details if it helps.

Without the driver, using the generic code I am able
to use the drive, in I think UDMA100 by letting the
BIOS set the drive to UDMA100 then manually setting
DMA mode on with hdparm.  However if I try to set the
modes manually with hdparm I can not select above
UDMA66.

I have tried this with kernel 2.4.10 and 2.4.11pre1.
My system is a Dual K7, SMP kernel, 512MB RAM.

My root filesystem is on a RAID0 array across 4
Quantum AtlasV 9GB U160 SCSI disks, two on each
channel of the onboard Adaptec.

I have tried to use the Fireball in the array as well
but for some reason performance reduced!  110MB/s with
hdparm -t compared to 70MB/s. Could this be because of
the lack of chipset driver?

One other thing is I am running with the preemt patch,
though I tested it without as well as I remember.

Please CC any replys to steven.newbury1@ntlworld.com
as  I am not on the list.
--
Steven Newbury


____________________________________________________________
Do You Yahoo!?
Get your free @yahoo.co.uk address at http://mail.yahoo.co.uk
or your free @yahoo.ie address at http://mail.yahoo.ie

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

end of thread, other threads:[~2001-10-05 21:26 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-27 21:26 AMD viper chipset and UDMA100 Sean Swallow
2001-09-27 21:36 ` Nicholas Knight
2001-09-27 21:59 ` Vojtech Pavlik
2001-09-27 22:16   ` Dan Hollis
2001-09-27 22:24     ` Vojtech Pavlik
2001-09-27 22:54       ` Dan Hollis
2001-09-28  2:21         ` Jacob Luna Lundberg
2001-09-27 23:37       ` Sean Swallow
2001-09-28 10:21         ` [patch] " Vojtech Pavlik
2001-10-05 21:26 Steven Newbury

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).