diff options
Diffstat (limited to 'drivers/ide/pci/sis5513.c')
-rw-r--r-- | drivers/ide/pci/sis5513.c | 253 |
1 files changed, 128 insertions, 125 deletions
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 512bb4c1fd5c..4b0b85d8faf5 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -59,10 +59,10 @@ #define ATA_16 0x01 #define ATA_33 0x02 #define ATA_66 0x03 -#define ATA_100a 0x04 // SiS730/SiS550 is ATA100 with ATA66 layout +#define ATA_100a 0x04 /* SiS730/SiS550 is ATA100 with ATA66 layout */ #define ATA_100 0x05 -#define ATA_133a 0x06 // SiS961b with 133 support -#define ATA_133 0x07 // SiS962/963 +#define ATA_133a 0x06 /* SiS961b with 133 support */ +#define ATA_133 0x07 /* SiS962/963 */ static u8 chipset_family; @@ -111,69 +111,70 @@ static const struct { Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ /* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */ -static u8 cycle_time_offset[] = {0,0,5,4,4,0,0}; -static u8 cycle_time_range[] = {0,0,2,3,3,4,4}; +static u8 cycle_time_offset[] = { 0, 0, 5, 4, 4, 0, 0 }; +static u8 cycle_time_range[] = { 0, 0, 2, 3, 3, 4, 4 }; static u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { - {0,0,0,0,0,0,0}, /* no udma */ - {0,0,0,0,0,0,0}, /* no udma */ - {3,2,1,0,0,0,0}, /* ATA_33 */ - {7,5,3,2,1,0,0}, /* ATA_66 */ - {7,5,3,2,1,0,0}, /* ATA_100a (730 specific), differences are on cycle_time range and offset */ - {11,7,5,4,2,1,0}, /* ATA_100 */ - {15,10,7,5,3,2,1}, /* ATA_133a (earliest 691 southbridges) */ - {15,10,7,5,3,2,1}, /* ATA_133 */ + { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ + { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ + { 3, 2, 1, 0, 0, 0, 0 }, /* ATA_33 */ + { 7, 5, 3, 2, 1, 0, 0 }, /* ATA_66 */ + { 7, 5, 3, 2, 1, 0, 0 }, /* ATA_100a (730 specific), + different cycle_time range and offset */ + { 11, 7, 5, 4, 2, 1, 0 }, /* ATA_100 */ + { 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133a (earliest 691 southbridges) */ + { 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133 */ }; /* CRC Valid Setup Time vary across IDE clock setting 33/66/100/133 See SiS962 data sheet for more detail */ static u8 cvs_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { - {0,0,0,0,0,0,0}, /* no udma */ - {0,0,0,0,0,0,0}, /* no udma */ - {2,1,1,0,0,0,0}, - {4,3,2,1,0,0,0}, - {4,3,2,1,0,0,0}, - {6,4,3,1,1,1,0}, - {9,6,4,2,2,2,2}, - {9,6,4,2,2,2,2}, + { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ + { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ + { 2, 1, 1, 0, 0, 0, 0 }, + { 4, 3, 2, 1, 0, 0, 0 }, + { 4, 3, 2, 1, 0, 0, 0 }, + { 6, 4, 3, 1, 1, 1, 0 }, + { 9, 6, 4, 2, 2, 2, 2 }, + { 9, 6, 4, 2, 2, 2, 2 }, }; /* Initialize time, Active time, Recovery time vary across IDE clock settings. These 3 arrays hold the register value for PIO0/1/2/3/4 and DMA0/1/2 mode in order */ static u8 ini_time_value[][8] = { - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {2,1,0,0,0,1,0,0}, - {4,3,1,1,1,3,1,1}, - {4,3,1,1,1,3,1,1}, - {6,4,2,2,2,4,2,2}, - {9,6,3,3,3,6,3,3}, - {9,6,3,3,3,6,3,3}, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, 1, 0, 0, 0, 1, 0, 0 }, + { 4, 3, 1, 1, 1, 3, 1, 1 }, + { 4, 3, 1, 1, 1, 3, 1, 1 }, + { 6, 4, 2, 2, 2, 4, 2, 2 }, + { 9, 6, 3, 3, 3, 6, 3, 3 }, + { 9, 6, 3, 3, 3, 6, 3, 3 }, }; static u8 act_time_value[][8] = { - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {9,9,9,2,2,7,2,2}, - {19,19,19,5,4,14,5,4}, - {19,19,19,5,4,14,5,4}, - {28,28,28,7,6,21,7,6}, - {38,38,38,10,9,28,10,9}, - {38,38,38,10,9,28,10,9}, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 9, 9, 9, 2, 2, 7, 2, 2 }, + { 19, 19, 19, 5, 4, 14, 5, 4 }, + { 19, 19, 19, 5, 4, 14, 5, 4 }, + { 28, 28, 28, 7, 6, 21, 7, 6 }, + { 38, 38, 38, 10, 9, 28, 10, 9 }, + { 38, 38, 38, 10, 9, 28, 10, 9 }, }; static u8 rco_time_value[][8] = { - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {9,2,0,2,0,7,1,1}, - {19,5,1,5,2,16,3,2}, - {19,5,1,5,2,16,3,2}, - {30,9,3,9,4,25,6,4}, - {40,12,4,12,5,34,12,5}, - {40,12,4,12,5,34,12,5}, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 9, 2, 0, 2, 0, 7, 1, 1 }, + { 19, 5, 1, 5, 2, 16, 3, 2 }, + { 19, 5, 1, 5, 2, 16, 3, 2 }, + { 30, 9, 3, 9, 4, 25, 6, 4 }, + { 40, 12, 4, 12, 5, 34, 12, 5 }, + { 40, 12, 4, 12, 5, 34, 12, 5 }, }; /* * Printing configuration */ /* Used for chipset type printing at boot time */ -static char* chipset_capability[] = { +static char *chipset_capability[] = { "ATA", "ATA 16", "ATA 33", "ATA 66", "ATA 100 (1st gen)", "ATA 100 (2nd gen)", @@ -272,7 +273,7 @@ static void sis_program_timings(ide_drive_t *drive, const u8 mode) sis_ata133_program_timings(drive, mode); } -static void config_drive_art_rwp (ide_drive_t *drive) +static void config_drive_art_rwp(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); @@ -346,7 +347,7 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed) sis_program_timings(drive, speed); } -static u8 sis5513_ata133_udma_filter(ide_drive_t *drive) +static u8 sis_ata133_udma_filter(ide_drive_t *drive) { struct pci_dev *dev = to_pci_dev(drive->hwif->dev); u32 regdw = 0; @@ -358,8 +359,7 @@ static u8 sis5513_ata133_udma_filter(ide_drive_t *drive) return (regdw & 0x08) ? ATA_UDMA6 : ATA_UDMA5; } -/* Chip detection and general config */ -static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name) +static int __devinit sis_find_family(struct pci_dev *dev) { struct pci_dev *host; int i = 0; @@ -381,7 +381,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c chipset_family = ATA_100a; } pci_dev_put(host); - + printk(KERN_INFO "SIS5513: %s %s controller\n", SiSHostChipInfo[i].name, chipset_capability[chipset_family]); } @@ -440,63 +440,60 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c } } - if (!chipset_family) - return -1; + return chipset_family; +} +static unsigned int __devinit init_chipset_sis5513(struct pci_dev *dev, + const char *name) +{ /* Make general config ops here 1/ tell IDE channels to operate in Compatibility mode only 2/ tell old chips to allow per drive IDE timings */ - { - u8 reg; - u16 regw; - - switch(chipset_family) { - case ATA_133: - /* SiS962 operation mode */ - pci_read_config_word(dev, 0x50, ®w); - if (regw & 0x08) - pci_write_config_word(dev, 0x50, regw&0xfff7); - pci_read_config_word(dev, 0x52, ®w); - if (regw & 0x08) - pci_write_config_word(dev, 0x52, regw&0xfff7); - break; - case ATA_133a: - case ATA_100: - /* Fixup latency */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80); - /* Set compatibility bit */ - pci_read_config_byte(dev, 0x49, ®); - if (!(reg & 0x01)) { - pci_write_config_byte(dev, 0x49, reg|0x01); - } - break; - case ATA_100a: - case ATA_66: - /* Fixup latency */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10); - - /* On ATA_66 chips the bit was elsewhere */ - pci_read_config_byte(dev, 0x52, ®); - if (!(reg & 0x04)) { - pci_write_config_byte(dev, 0x52, reg|0x04); - } - break; - case ATA_33: - /* On ATA_33 we didn't have a single bit to set */ - pci_read_config_byte(dev, 0x09, ®); - if ((reg & 0x0f) != 0x00) { - pci_write_config_byte(dev, 0x09, reg&0xf0); - } - case ATA_16: - /* force per drive recovery and active timings - needed on ATA_33 and below chips */ - pci_read_config_byte(dev, 0x52, ®); - if (!(reg & 0x08)) { - pci_write_config_byte(dev, 0x52, reg|0x08); - } - break; - } + u8 reg; + u16 regw; + + switch (chipset_family) { + case ATA_133: + /* SiS962 operation mode */ + pci_read_config_word(dev, 0x50, ®w); + if (regw & 0x08) + pci_write_config_word(dev, 0x50, regw&0xfff7); + pci_read_config_word(dev, 0x52, ®w); + if (regw & 0x08) + pci_write_config_word(dev, 0x52, regw&0xfff7); + break; + case ATA_133a: + case ATA_100: + /* Fixup latency */ + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80); + /* Set compatibility bit */ + pci_read_config_byte(dev, 0x49, ®); + if (!(reg & 0x01)) + pci_write_config_byte(dev, 0x49, reg|0x01); + break; + case ATA_100a: + case ATA_66: + /* Fixup latency */ + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10); + + /* On ATA_66 chips the bit was elsewhere */ + pci_read_config_byte(dev, 0x52, ®); + if (!(reg & 0x04)) + pci_write_config_byte(dev, 0x52, reg|0x04); + break; + case ATA_33: + /* On ATA_33 we didn't have a single bit to set */ + pci_read_config_byte(dev, 0x09, ®); + if ((reg & 0x0f) != 0x00) + pci_write_config_byte(dev, 0x09, reg&0xf0); + case ATA_16: + /* force per drive recovery and active timings + needed on ATA_33 and below chips */ + pci_read_config_byte(dev, 0x52, ®); + if (!(reg & 0x08)) + pci_write_config_byte(dev, 0x52, reg|0x08); + break; } return 0; @@ -517,7 +514,7 @@ static const struct sis_laptop sis_laptop[] = { { 0, } }; -static u8 __devinit ata66_sis5513(ide_hwif_t *hwif) +static u8 __devinit sis_cable_detect(ide_hwif_t *hwif) { struct pci_dev *pdev = to_pci_dev(hwif->dev); const struct sis_laptop *lap = &sis_laptop[0]; @@ -546,38 +543,44 @@ static u8 __devinit ata66_sis5513(ide_hwif_t *hwif) return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; } -static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) -{ - u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f }; - - hwif->set_pio_mode = &sis_set_pio_mode; - hwif->set_dma_mode = &sis_set_dma_mode; - - if (chipset_family >= ATA_133) - hwif->udma_filter = sis5513_ata133_udma_filter; - - hwif->cable_detect = ata66_sis5513; - - if (hwif->dma_base == 0) - return; +static const struct ide_port_ops sis_port_ops = { + .set_pio_mode = sis_set_pio_mode, + .set_dma_mode = sis_set_dma_mode, + .cable_detect = sis_cable_detect, +}; - hwif->ultra_mask = udma_rates[chipset_family]; -} +static const struct ide_port_ops sis_ata133_port_ops = { + .set_pio_mode = sis_set_pio_mode, + .set_dma_mode = sis_set_dma_mode, + .udma_filter = sis_ata133_udma_filter, + .cable_detect = sis_cable_detect, +}; static const struct ide_port_info sis5513_chipset __devinitdata = { .name = "SIS5513", .init_chipset = init_chipset_sis5513, - .init_hwif = init_hwif_sis5513, - .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA | - IDE_HFLAG_BOOTABLE, + .enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} }, + .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, }; static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - return ide_setup_pci_device(dev, &sis5513_chipset); + struct ide_port_info d = sis5513_chipset; + u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f }; + + if (sis_find_family(dev) == 0) + return -ENOTSUPP; + + if (chipset_family >= ATA_133) + d.port_ops = &sis_ata133_port_ops; + else + d.port_ops = &sis_port_ops; + + d.udma_mask = udma_rates[chipset_family]; + + return ide_setup_pci_device(dev, &d); } static const struct pci_device_id sis5513_pci_tbl[] = { |