summaryrefslogtreecommitdiffstats
path: root/drivers/ide/via82cxxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/via82cxxx.c')
-rw-r--r--drivers/ide/via82cxxx.c186
1 files changed, 124 insertions, 62 deletions
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index afa1cc5b6..bf8e27640 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/block/via82cxxx.c Version 0.07 Feb. 10, 2000
+ * linux/drivers/ide/via82cxxx.c Version 0.08 Mar. 18, 2000
*
* Copyright (C) 1998-99 Michel Aubry, Maintainer
* Copyright (C) 1999 Jeff Garzik, MVP4 Support
@@ -143,14 +143,14 @@ static const struct {
#include <linux/stat.h>
#include <linux/proc_fs.h>
-static char *FIFO_str[] = {
+static char *FIFO_str[] __initdata = {
" 1 ",
"3/4",
"1/2",
"1/4"
};
-static char *control3_str[] = {
+static char *control3_str[] __initdata = {
"No limitation",
"64",
"128",
@@ -516,6 +516,62 @@ static int via_set_fifoconfig(ide_hwif_t *hwif)
#ifdef CONFIG_VIA82CXXX_TUNING
+struct chipset_bus_clock_list_entry {
+ unsigned short bus_speed;
+ byte xfer_speed;
+ byte chipset_settings;
+};
+
+PCI_DEVICE_ID_VIA_82C586_1
+PCI_DEVICE_ID_VIA_82C596
+PCI_DEVICE_ID_VIA_82C686
+PCI_DEVICE_ID_VIA_8231
+
+PCI_DEVICE_ID_VIA_82C586_1 TYPE_1
+PCI_DEVICE_ID_VIA_82C596 TYPE_2
+PCI_DEVICE_ID_VIA_82C686 TYPE_2
+PCI_DEVICE_ID_VIA_82C596 TYPE_3
+PCI_DEVICE_ID_VIA_82C686 TYPE_3
+PCI_DEVICE_ID_VIA_8231 TYPE_4
+
+struct chipset_bus_clock_list_entry ultra_33_base [] = {
+{ TYPE_1,25,0x00,0x00,0x60,0x61,0x62,0x03,0x20,0x31,0x65,0x65,0xA8 },
+{ TYPE_1,33,0x00,0x00,0x60,0x61,0x62,0x03,0x20,0x31,0x65,0x65,0xA8 },
+{ TYPE_1,37,0x00,0x00,0x60,0x61,0x62,0x03,0x21,0x32,0x76,0x76,0xA9 },
+{ TYPE_2,25,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 },
+{ TYPE_2,33,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 },
+{ TYPE_2,37,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x31,0x42,0x87,0x87,0xDB },
+{ TYPE_2,41,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x32,0x53,0xA8,0xA8,0xFE },
+{ TYPE_3,25,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 },
+{ TYPE_3,33,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 },
+{ TYPE_3,37,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x31,0x42,0x87,0x87,0xDB },
+{ TYPE_3,41,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x32,0x53,0xA8,0xA8,0xFE },
+{ TYPE_4,0,0,0,0,0,0,0,0,0,0,0,0 },
+{ 0,0,0,0,0,0,0,0,0,0,0,0,0 }
+};
+
+struct chipset_bus_clock_list_entry timing_66_base [] = {
+ { 37, XFER_PIO_4, 0x21 },
+ { 37, XFER_PIO_3, 0x32 },
+ { 37, XFER_PIO_2, 0x76 },
+ { 37, XFER_PIO_1, 0x76 },
+ { 37, XFER_PIO_0, 0xA9 },
+ { ANY, XFER_PIO_4, 0x20 },
+ { ANY, XFER_PIO_3, 0x31 },
+ { ANY, XFER_PIO_2, 0x65 },
+ { ANY, XFER_PIO_1, 0x65 },
+ { ANY, XFER_PIO_0, 0xA8 },
+};
+
+static byte pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
+{
+ for ( ; chipset_table->xfer_speed ; chipset_table++)
+ if (chipset_table->xfer_speed == speed) {
+ return chipset_table->chipset_settings;
+ }
+ return 0x01208585;
+}
+
static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed)
{
struct hd_driveid *id = drive->id;
@@ -539,7 +595,7 @@ static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed)
case 2: ata2_pci = 0x4a; ata3_pci = 0x52; break;
case 3: ata2_pci = 0x4b; ata3_pci = 0x53; break;
default:
- return err;
+ return -1;
}
pci_read_config_byte(dev, ata2_pci, &timing);
@@ -575,6 +631,57 @@ static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed)
return(err);
}
+static void config_chipset_for_pio (ide_drive_t *drive)
+{
+ 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;
+ }
+
+ timing = (xfer_pio >= pio) ? xfer_pio : pio;
+ 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;
+ }
+ (void) via82cxxx_tune_chipset(drive, speed);
+}
+
+static void via82cxxx_tune_drive (ide_drive_t *drive, byte 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;
+ }
+ (void) via82cxxx_tune_chipset(drive, speed);
+}
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
@@ -617,56 +724,6 @@ static int config_chipset_for_dma (ide_drive_t *drive)
return rval;
}
-static void config_chipset_for_pio (ide_drive_t *drive)
-{
- 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;
- }
-
- timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
- 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;
- }
- (void) via82cxxx_tune_chipset(drive, speed);
-}
-
-static void via82cxxx_tune_drive (ide_drive_t *drive, byte 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;
- }
- (void) via82cxxx_tune_chipset(drive, speed);
-}
-
static int config_drive_xfer_rate (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
@@ -726,6 +783,7 @@ int via82cxxx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
}
return ide_dmaproc(func, drive); /* use standard DMA stuff */
}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
#endif /* CONFIG_VIA82CXXX_TUNING */
unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name)
@@ -745,7 +803,7 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name)
host_dev = host;
printk(ApolloHostChipInfo[i].name);
-
+ printk("\n");
for (j = 0; j < arraysize (ApolloISAChipInfo) && !isa_dev; j++) {
if (ApolloISAChipInfo[j].host_id !=
ApolloHostChipInfo[i].host_id)
@@ -777,9 +835,11 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name)
}
#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
- via_proc = 1;
- bmide_dev = dev;
- via_display_info = &via_get_info;
+ if (!via_proc) {
+ via_proc = 1;
+ bmide_dev = dev;
+ via_display_info = &via_get_info;
+ }
#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS*/
return 0;
@@ -797,13 +857,15 @@ void __init ide_init_via82cxxx (ide_hwif_t *hwif)
#ifdef CONFIG_VIA82CXXX_TUNING
hwif->tuneproc = &via82cxxx_tune_drive;
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
+ hwif->autodma = 0;
+#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->dmaproc = &via82cxxx_dmaproc;
- } else {
- hwif->autodma = 0;
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
+ hwif->autodma = 1;
}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
#endif /* CONFIG_VIA82CXXX_TUNING */
}