public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC] SIS5513 ATA100 support
@ 2001-12-24 22:46 Lionel Bouton
  2001-12-25 19:13 ` Lionel Bouton
  0 siblings, 1 reply; 4+ messages in thread
From: Lionel Bouton @ 2001-12-24 22:46 UTC (permalink / raw)
  To: Daniela Engert; +Cc: linux-kernel, Chris Shutters

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

Daniela,

here's my first patch to sis5513.c : this should set the correct timings 
for ATA100 chips (and hopefully say goodbye to heavy fs corruption in 
UDMA modes).

It compiles cleanly but is **not yet tested**. I'm currently waiting for 
~30GB to move from my test drive to a safe location (gory details: 
source DMA drive, destination PIO drive, accross NFS on a 100kKiB :-P 
full-duplex Ethernet).

If there's an obvious mistake please tell me (I've a couple of hours to 
wait for the transfer before testing with and without the patch on a 
"blank" ATA-100 drive).

If others want to have a look or even (I repeat **not yet tested**) try 
this code **on backuped data** they're more than welcome.

If you want to have a quick look at the whole new sis5513.c :

http://gyver.homeip.net/sis5513.c



I'm now on to a more general sis5513.c cleanup :

1/ There is some suspicious code (sis_get_info seems broken to me from 
ATA66 on and config_art_rwp_pio is not yet ATA100-chip friendly)
2/ I'll probably move to per chip types funcs as the current generic 
ones become uglier and uglier at each new sis chipset).


LB

[-- Attachment #2: sis.patch --]
[-- Type: text/plain, Size: 4850 bytes --]

--- linux-orig/drivers/ide/sis5513.c	Fri Sep  7 18:28:38 2001
+++ linux/drivers/ide/sis5513.c	Mon Dec 24 22:46:21 2001
@@ -32,11 +32,13 @@
 #define SIS5513_DEBUG_DRIVE_INFO	0
 
 static struct pci_dev *host_dev = NULL;
+static unsigned int capabilities = 0;
 
 #define SIS5513_FLAG_ATA_00		0x00000000
 #define SIS5513_FLAG_ATA_16		0x00000001
 #define SIS5513_FLAG_ATA_33		0x00000002
 #define SIS5513_FLAG_ATA_66		0x00000004
+#define SIS5513_FLAG_ATA_100		0x00000008
 #define SIS5513_FLAG_LATENCY		0x00000010
 
 static const struct {
@@ -48,15 +50,15 @@
 	{ "SiS540",	PCI_DEVICE_ID_SI_540,	SIS5513_FLAG_ATA_66, },
 	{ "SiS620",	PCI_DEVICE_ID_SI_620,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
 	{ "SiS630",	PCI_DEVICE_ID_SI_630,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS635",	PCI_DEVICE_ID_SI_635,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS635",	PCI_DEVICE_ID_SI_635,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
 	{ "SiS640",	PCI_DEVICE_ID_SI_640,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS645",	PCI_DEVICE_ID_SI_645,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS650",	PCI_DEVICE_ID_SI_650,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS730",	PCI_DEVICE_ID_SI_730,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS735",	PCI_DEVICE_ID_SI_735,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS740",	PCI_DEVICE_ID_SI_740,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS745",	PCI_DEVICE_ID_SI_745,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS750",	PCI_DEVICE_ID_SI_750,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS645",	PCI_DEVICE_ID_SI_645,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS650",	PCI_DEVICE_ID_SI_650,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS730",	PCI_DEVICE_ID_SI_730,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS735",	PCI_DEVICE_ID_SI_735,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS740",	PCI_DEVICE_ID_SI_740,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS745",	PCI_DEVICE_ID_SI_745,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS750",	PCI_DEVICE_ID_SI_750,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
 	{ "SiS5591",	PCI_DEVICE_ID_SI_5591,	SIS5513_FLAG_ATA_33, },
 	{ "SiS5597",	PCI_DEVICE_ID_SI_5597,	SIS5513_FLAG_ATA_33, },
 	{ "SiS5600",	PCI_DEVICE_ID_SI_5600,	SIS5513_FLAG_ATA_33, },
@@ -229,6 +231,7 @@
 byte sis_proc = 0;
 extern char *ide_xfer_verbose (byte xfer_rate);
 
+/* Enables Prefetch and Postwrite on drive */
 static void config_drive_art_rwp (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -298,8 +301,8 @@
 	 * Do a blanket clear of active and recovery timings.
 	 */
 
-	test1 &= ~0x07;
-	test2 &= ~0x0F;
+	test1 &= ~0x0F;
+	test2 &= ~0x07;
 
 	switch(timing) {
 		case 4:		test1 |= 0x01; test2 |= 0x03; break;
@@ -379,6 +382,7 @@
 	pci_read_config_byte(dev, drive_pci, &test1);
 	pci_read_config_byte(dev, drive_pci|0x01, &test2);
 
+	/* If not an UDMA mode switch off udma bit */
 	if ((speed <= XFER_MW_DMA_2) && (test2 & 0x80)) {
 		pci_write_config_byte(dev, drive_pci|0x01, test2 & ~0x80);
 		pci_read_config_byte(dev, drive_pci|0x01, &test2);
@@ -386,7 +390,31 @@
 		pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);
 	}
 
-	switch(speed) {
+	if (capabilities & SIS5513_FLAG_ATA_100) {
+		switch(speed) {
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		case XFER_UDMA_5: mask = 0x01; break;
+		case XFER_UDMA_4: mask = 0x02; break;
+		case XFER_UDMA_3: mask = 0x04; break;
+		case XFER_UDMA_2: mask = 0x05; break;
+		case XFER_UDMA_1: mask = 0x07; break;
+		case XFER_UDMA_0: mask = 0x0B; break;
+		case XFER_MW_DMA_2:
+		case XFER_MW_DMA_1:
+		case XFER_MW_DMA_0:
+		case XFER_SW_DMA_2:
+		case XFER_SW_DMA_1:
+		case XFER_SW_DMA_0: break;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+		case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));
+		case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));
+		case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));
+		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
+		case XFER_PIO_0:
+		default:	 return((int) config_chipset_for_pio(drive, 0));
+		}
+	} else {
+		switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 		case XFER_UDMA_5: mask = 0x80; break;
 		case XFER_UDMA_4: mask = 0x90; break;
@@ -407,6 +435,7 @@
 		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
 		case XFER_PIO_0:
 		default:	 return((int) config_chipset_for_pio(drive, 0));
+		}
 	}
 
 	if (speed > XFER_MW_DMA_2)
@@ -583,6 +612,7 @@
 			continue;
 
 		host_dev = host;
+		capabilities = SiSHostChipInfo[i].flags;
 		printk(SiSHostChipInfo[i].name);
 		printk("\n");
 		if (SiSHostChipInfo[i].flags & SIS5513_FLAG_LATENCY) {

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

* Re: [RFC] SIS5513 ATA100 support
  2001-12-24 22:46 [RFC] SIS5513 ATA100 support Lionel Bouton
@ 2001-12-25 19:13 ` Lionel Bouton
  2001-12-26 20:53   ` Lionel Bouton
  2001-12-26 20:55   ` Lionel Bouton
  0 siblings, 2 replies; 4+ messages in thread
From: Lionel Bouton @ 2001-12-25 19:13 UTC (permalink / raw)
  To: Daniela Engert, linux-kernel; +Cc: Chris Shutters

Lionel Bouton wrote:

> 
> 
> here's my first patch to sis5513.c : this should set the correct timings 
> for ATA100 chips (and hopefully say goodbye to heavy fs corruption in 
> UDMA modes).
> 


Problem not yet solved. I'm back to the drawing board but now I have a 
"reliable" way of triggering the problem.


> It compiles cleanly but is **not yet tested**.

 >

> If there's an obvious mistake please tell me 


Don't know yet if it's obvious, but there's one.

> 
> If others want to have a look or even (I repeat **not yet tested**) try 
> this code **on backuped data** they're more than welcome.
> 


Having a look at the code is always welcome. But don't waste your time 
and data testing...


> If you want to have a quick look at the whole new sis5513.c :
> 
> http://gyver.homeip.net/sis5513.c
> 
> 


LB


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

* Re: [RFC] SIS5513 ATA100 support
  2001-12-25 19:13 ` Lionel Bouton
@ 2001-12-26 20:53   ` Lionel Bouton
  2001-12-26 20:55   ` Lionel Bouton
  1 sibling, 0 replies; 4+ messages in thread
From: Lionel Bouton @ 2001-12-26 20:53 UTC (permalink / raw)
  To: linux-kernel, Andre Hedrick

Hello,

I'm back with new code.

This one doesn't work on my sis735 either :-( but after having 
triple-checked my code I don't see why :-((. Time to show the code to 
others...

If someone familiar with pci-ide code could just take a quick look...

The goal is only working ata-100 inits. There's code in sis5513.c that 
could use a little cleanup but I'll wait working ata-100 inits to work 
on that.

You have an edited (commented) diff from original sis5513.c and the real 
patch attached.

A complete new sis5513.c is available for more conveniance at :
http://gyver.homeip.net/sis5513.c

LB.


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

* Re: [RFC] SIS5513 ATA100 support
  2001-12-25 19:13 ` Lionel Bouton
  2001-12-26 20:53   ` Lionel Bouton
@ 2001-12-26 20:55   ` Lionel Bouton
  1 sibling, 0 replies; 4+ messages in thread
From: Lionel Bouton @ 2001-12-26 20:55 UTC (permalink / raw)
  To: linux-kernel, Andre Hedrick

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

Reads better with attachements.

Hello,

I'm back with new code.

This one doesn't work on my sis735 either :-( but after having
triple-checked my code I don't see why :-((. Time to show the code to
others...

If someone familiar with pci-ide code could just take a quick look...

The goal is only working ata-100 inits. There's code in sis5513.c that
could use a little cleanup but I'll wait working ata-100 inits to work
on that.

You have an edited (commented) diff from original sis5513.c and the real
patch attached.

A complete new sis5513.c is available for more conveniance at :
http://gyver.homeip.net/sis5513.c

LB.


[-- Attachment #2: sis.diff --]
[-- Type: text/plain, Size: 6257 bytes --]

+++ Add a Flag for chips supporting ata-100 +++

 #define SIS5513_FLAG_ATA_16		0x00000001
 #define SIS5513_FLAG_ATA_33		0x00000002
 #define SIS5513_FLAG_ATA_66		0x00000004
+#define SIS5513_FLAG_ATA_100		0x00000008
 #define SIS5513_FLAG_LATENCY		0x00000010


+++ Holds the flags of the detected chip +++

+static unsigned int capabilities = 0x00000000;
+


+++ Changed flags in order to reflect capabilities +++
??? Are there some chips supporting ata-100 I missed ???

 static const struct {
 	const char *name;
 	unsigned short host_id;
 	{ "SiS540",	PCI_DEVICE_ID_SI_540,	SIS5513_FLAG_ATA_66, },
 	{ "SiS620",	PCI_DEVICE_ID_SI_620,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
 	{ "SiS630",	PCI_DEVICE_ID_SI_630,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS635",	PCI_DEVICE_ID_SI_635,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS635",	PCI_DEVICE_ID_SI_635,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
 	{ "SiS640",	PCI_DEVICE_ID_SI_640,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS645",	PCI_DEVICE_ID_SI_645,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS650",	PCI_DEVICE_ID_SI_650,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS730",	PCI_DEVICE_ID_SI_730,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS735",	PCI_DEVICE_ID_SI_735,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS740",	PCI_DEVICE_ID_SI_740,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS745",	PCI_DEVICE_ID_SI_745,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS750",	PCI_DEVICE_ID_SI_750,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS645",	PCI_DEVICE_ID_SI_645,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS650",	PCI_DEVICE_ID_SI_650,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS730",	PCI_DEVICE_ID_SI_730,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS735",	PCI_DEVICE_ID_SI_735,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS740",	PCI_DEVICE_ID_SI_740,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS745",	PCI_DEVICE_ID_SI_745,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS750",	PCI_DEVICE_ID_SI_750,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
 	{ "SiS5591",	PCI_DEVICE_ID_SI_5591,	SIS5513_FLAG_ATA_33, },
 	{ "SiS5597",	PCI_DEVICE_ID_SI_5597,	SIS5513_FLAG_ATA_33, },
 	{ "SiS5600",	PCI_DEVICE_ID_SI_5600,	SIS5513_FLAG_ATA_33, },
 

+++ PIO timing register layout is different for ata-100 use the new one +++
 
+	if (capabilities && SIS5513_FLAG_ATA_100) {
+		switch(timing) { /*   active  recovery
+					  v     v */
+		case 4:		test1 = 0x30|0x01; break;
+		case 3:		test1 = 0x30|0x03; break;
+		case 2:		test1 = 0x40|0x04; break;
+		case 1:		test1 = 0x60|0x07; break;
+		default:	break;
+		}
+		pci_write_config_byte(dev, drive_pci, test1);
+		return; /* temporary hack for tests */
+	}
+
 	pci_read_config_byte(dev, drive_pci, &test1);
 	pci_read_config_byte(dev, drive_pci|0x01, &test2);


+++ The masks below were wrong from the beginning +++
 
 	 * Do a blanket clear of active and recovery timings.
 	 */

-	test1 &= ~0x07;
-	test2 &= ~0x0F;
+	test1 &= ~0x0F;
+	test2 &= ~0x07;


+++ UDMA mode timing are set on a different base (10ns instead of 1/2 PCI_CLOCK) +++
+++ and the register layout is different too +++
  
-	switch(speed) {
+	if (capabilities & SIS5513_FLAG_ATA_100) {
+		switch(speed) {
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		case XFER_UDMA_5: mask = 0x01; break;
+		case XFER_UDMA_4: mask = 0x02; break;
+		case XFER_UDMA_3: mask = 0x04; break;
+		case XFER_UDMA_2: mask = 0x05; break;
+		case XFER_UDMA_1: mask = 0x07; break;
+		case XFER_UDMA_0: mask = 0x0B; break;
+		case XFER_MW_DMA_2:
+		case XFER_MW_DMA_1:
+		case XFER_MW_DMA_0:
+		case XFER_SW_DMA_2:
+		case XFER_SW_DMA_1:
+		case XFER_SW_DMA_0: break;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+		case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));
+		case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));
+		case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));
+		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
+		case XFER_PIO_0:
+		default:	 return((int) config_chipset_for_pio(drive, 0));
+		}
+	} else {
+		switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 		case XFER_UDMA_5: mask = 0x80; break;
 		case XFER_UDMA_4: mask = 0x90; break;
@@ -407,10 +450,16 @@
 		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
 		case XFER_PIO_0:
 		default:	 return((int) config_chipset_for_pio(drive, 0));
+		}
 	}
 

+++ Adapt the code to the register layout : 0x80 for UDMA enable +++
+++ doesn't have to use a pci_read_config before as we set the whole register +++

-	if (speed > XFER_MW_DMA_2)
-		pci_write_config_byte(dev, drive_pci|0x01, test2|mask);
+	if (speed > XFER_MW_DMA_2) {
+		if (capabilities & SIS5513_FLAG_ATA_100) {
+			pci_write_config_byte(dev, drive_pci|0x01, 0x80|mask);
+		} else {
+			pci_write_config_byte(dev, drive_pci|0x01, test2|mask);
+		}
+	}
 
 	drive->current_speed = speed;
 	return ((int) ide_config_drive_speed(drive, speed));
@@ -583,6 +632,7 @@
 			continue;


+++ Here (pci_init_sis5513) we store the capabilities flags +++
+++ used everywhere else to activate ata-100 specific code +++

 		host_dev = host;
+		capabilities = SiSHostChipInfo[i].flags;
 		printk(SiSHostChipInfo[i].name);
 		printk("\n");
 		if (SiSHostChipInfo[i].flags & SIS5513_FLAG_LATENCY) {
@@ -592,12 +642,22 @@
 	}
 

+++ The Compatibility mode bit changed from reg52h bit 2 to reg49h bit 0 +++

 	if (host_dev) {
-		byte reg52h = 0;
+		if (capabilities & SIS5513_FLAG_ATA_100) {
+			byte reg49h = 0;
 
-		pci_read_config_byte(dev, 0x52, &reg52h);
-		if (!(reg52h & 0x04)) {
-			/* set IDE controller to operate in Compabitility mode only */
-			pci_write_config_byte(dev, 0x52, reg52h|0x04);
+			pci_read_config_byte(dev, 0x49, &reg49h);
+			if (!(reg49h & 0x01)) {
+				/* set IDE controller to operate in Compabitility mode only */
+				pci_write_config_byte(dev, 0x49, reg49h|0x01);
+			}
+		} else {
+			byte reg52h = 0;
+
+			pci_read_config_byte(dev, 0x52, &reg52h);
+			if (!(reg52h & 0x04)) {
+				/* set IDE controller to operate in Compabitility mode only */
+				pci_write_config_byte(dev, 0x52, reg52h|0x04);
+			}
 		}
 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
 		if (!sis_proc) {

[-- Attachment #3: sis.patch2 --]
[-- Type: text/plain, Size: 6571 bytes --]

--- /usr/src/linux/drivers/ide/sis5513.c	Fri Sep  7 18:28:38 2001
+++ sis5513.c	Wed Dec 26 21:35:10 2001
@@ -37,8 +37,11 @@
 #define SIS5513_FLAG_ATA_16		0x00000001
 #define SIS5513_FLAG_ATA_33		0x00000002
 #define SIS5513_FLAG_ATA_66		0x00000004
+#define SIS5513_FLAG_ATA_100		0x00000008
 #define SIS5513_FLAG_LATENCY		0x00000010
 
+static unsigned int capabilities = 0x00000000;
+
 static const struct {
 	const char *name;
 	unsigned short host_id;
@@ -48,15 +51,15 @@
 	{ "SiS540",	PCI_DEVICE_ID_SI_540,	SIS5513_FLAG_ATA_66, },
 	{ "SiS620",	PCI_DEVICE_ID_SI_620,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
 	{ "SiS630",	PCI_DEVICE_ID_SI_630,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS635",	PCI_DEVICE_ID_SI_635,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS635",	PCI_DEVICE_ID_SI_635,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
 	{ "SiS640",	PCI_DEVICE_ID_SI_640,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS645",	PCI_DEVICE_ID_SI_645,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS650",	PCI_DEVICE_ID_SI_650,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS730",	PCI_DEVICE_ID_SI_730,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS735",	PCI_DEVICE_ID_SI_735,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS740",	PCI_DEVICE_ID_SI_740,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS745",	PCI_DEVICE_ID_SI_745,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
-	{ "SiS750",	PCI_DEVICE_ID_SI_750,	SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+	{ "SiS645",	PCI_DEVICE_ID_SI_645,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS650",	PCI_DEVICE_ID_SI_650,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS730",	PCI_DEVICE_ID_SI_730,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS735",	PCI_DEVICE_ID_SI_735,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS740",	PCI_DEVICE_ID_SI_740,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS745",	PCI_DEVICE_ID_SI_745,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+	{ "SiS750",	PCI_DEVICE_ID_SI_750,	SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
 	{ "SiS5591",	PCI_DEVICE_ID_SI_5591,	SIS5513_FLAG_ATA_33, },
 	{ "SiS5597",	PCI_DEVICE_ID_SI_5597,	SIS5513_FLAG_ATA_33, },
 	{ "SiS5600",	PCI_DEVICE_ID_SI_5600,	SIS5513_FLAG_ATA_33, },
@@ -229,6 +232,7 @@
 byte sis_proc = 0;
 extern char *ide_xfer_verbose (byte xfer_rate);
 
+/* Enables Prefetch and Postwrite on drive */
 static void config_drive_art_rwp (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -245,6 +249,7 @@
 		pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
 }
 
+/* Set active and recovery time */
 static void config_art_rwp_pio (ide_drive_t *drive, byte pio)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -291,6 +296,19 @@
 		default:	return;
 	}
 
+	if (capabilities && SIS5513_FLAG_ATA_100) {
+		switch(timing) { /*   active  recovery
+					  v     v */
+		case 4:		test1 = 0x30|0x01; break;
+		case 3:		test1 = 0x30|0x03; break;
+		case 2:		test1 = 0x40|0x04; break;
+		case 1:		test1 = 0x60|0x07; break;
+		default:	break;
+		}
+		pci_write_config_byte(dev, drive_pci, test1);
+		return; /* temporary hack for tests */
+	}
+
 	pci_read_config_byte(dev, drive_pci, &test1);
 	pci_read_config_byte(dev, drive_pci|0x01, &test2);
 
@@ -298,8 +316,8 @@
 	 * Do a blanket clear of active and recovery timings.
 	 */
 
-	test1 &= ~0x07;
-	test2 &= ~0x0F;
+	test1 &= ~0x0F;
+	test2 &= ~0x07;
 
 	switch(timing) {
 		case 4:		test1 |= 0x01; test2 |= 0x03; break;
@@ -379,6 +397,7 @@
 	pci_read_config_byte(dev, drive_pci, &test1);
 	pci_read_config_byte(dev, drive_pci|0x01, &test2);
 
+	/* If not an UDMA mode switch off udma bit */
 	if ((speed <= XFER_MW_DMA_2) && (test2 & 0x80)) {
 		pci_write_config_byte(dev, drive_pci|0x01, test2 & ~0x80);
 		pci_read_config_byte(dev, drive_pci|0x01, &test2);
@@ -386,7 +405,31 @@
 		pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);
 	}
 
-	switch(speed) {
+	if (capabilities & SIS5513_FLAG_ATA_100) {
+		switch(speed) {
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		case XFER_UDMA_5: mask = 0x01; break;
+		case XFER_UDMA_4: mask = 0x02; break;
+		case XFER_UDMA_3: mask = 0x04; break;
+		case XFER_UDMA_2: mask = 0x05; break;
+		case XFER_UDMA_1: mask = 0x07; break;
+		case XFER_UDMA_0: mask = 0x0B; break;
+		case XFER_MW_DMA_2:
+		case XFER_MW_DMA_1:
+		case XFER_MW_DMA_0:
+		case XFER_SW_DMA_2:
+		case XFER_SW_DMA_1:
+		case XFER_SW_DMA_0: break;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+		case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));
+		case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));
+		case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));
+		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
+		case XFER_PIO_0:
+		default:	 return((int) config_chipset_for_pio(drive, 0));
+		}
+	} else {
+		switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 		case XFER_UDMA_5: mask = 0x80; break;
 		case XFER_UDMA_4: mask = 0x90; break;
@@ -407,10 +450,16 @@
 		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
 		case XFER_PIO_0:
 		default:	 return((int) config_chipset_for_pio(drive, 0));
+		}
 	}
 
-	if (speed > XFER_MW_DMA_2)
-		pci_write_config_byte(dev, drive_pci|0x01, test2|mask);
+	if (speed > XFER_MW_DMA_2) {
+		if (capabilities & SIS5513_FLAG_ATA_100) {
+			pci_write_config_byte(dev, drive_pci|0x01, 0x80|mask);
+		} else {
+			pci_write_config_byte(dev, drive_pci|0x01, test2|mask);
+		}
+	}
 
 	drive->current_speed = speed;
 	return ((int) ide_config_drive_speed(drive, speed));
@@ -583,6 +632,7 @@
 			continue;
 
 		host_dev = host;
+		capabilities = SiSHostChipInfo[i].flags;
 		printk(SiSHostChipInfo[i].name);
 		printk("\n");
 		if (SiSHostChipInfo[i].flags & SIS5513_FLAG_LATENCY) {
@@ -592,12 +642,22 @@
 	}
 
 	if (host_dev) {
-		byte reg52h = 0;
+		if (capabilities & SIS5513_FLAG_ATA_100) {
+			byte reg49h = 0;
 
-		pci_read_config_byte(dev, 0x52, &reg52h);
-		if (!(reg52h & 0x04)) {
-			/* set IDE controller to operate in Compabitility mode only */
-			pci_write_config_byte(dev, 0x52, reg52h|0x04);
+			pci_read_config_byte(dev, 0x49, &reg49h);
+			if (!(reg49h & 0x01)) {
+				/* set IDE controller to operate in Compabitility mode only */
+				pci_write_config_byte(dev, 0x49, reg49h|0x01);
+			}
+		} else {
+			byte reg52h = 0;
+
+			pci_read_config_byte(dev, 0x52, &reg52h);
+			if (!(reg52h & 0x04)) {
+				/* set IDE controller to operate in Compabitility mode only */
+				pci_write_config_byte(dev, 0x52, reg52h|0x04);
+			}
 		}
 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
 		if (!sis_proc) {

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

end of thread, other threads:[~2001-12-26 20:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-12-24 22:46 [RFC] SIS5513 ATA100 support Lionel Bouton
2001-12-25 19:13 ` Lionel Bouton
2001-12-26 20:53   ` Lionel Bouton
2001-12-26 20:55   ` Lionel Bouton

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