11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz> 5e13ee546bb06453939014c7b854e77fb643fd6f1Bartlomiej Zolnierkiewicz * Copyright (C) 2007-2009 Bartlomiej Zolnierkiewicz 66b8cf7724bd0f8ae1f61937c5f40f4dbbda40960Bartlomiej Zolnierkiewicz * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * May be copied or modified under the terms of the GNU General Public License 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Thanks : 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SiS Taiwan : for direct support and hardware. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Daniela Engert : for initial ATA100 advices and numerous others. 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * John Fremlin, Manfred Spraul, Dave Morgan, Peter Kjellerstedt : 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for checking code correctness, providing patches. 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Original tests and design on the SiS620 chipset. 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ATA100 tests and design on the SiS735 chipset. 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ATA16/33 support from specs 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ATA133 support for SiS961/962 by L.C. Chang <lcchang@sis.com.tw> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ATA133 961/962/963 fixes by Vojtech Pavlik <vojtech@suse.cz> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Documentation: 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SiS chipset documentation available under NDA to companies only 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (not to individuals). 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The original SiS5513 comes from a SiS5511/55112/5513 chipset. The original 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SiS5513 was also used in the SiS5596/5513 chipset. Thus if we see a SiS5511 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or SiS5596, we can assume we see the first MWDMA-16 capable SiS5513 chip. 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Later SiS chipsets integrated the 5513 functionality into the NorthBridge, 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * starting with SiS5571 and up to SiS745. The PCI ID didn't change, though. We 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * can figure out that we have a more modern and more capable 5513 by looking 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for the respective NorthBridge IDs. 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Even later (96x family) SiS chipsets use the MuTIOL link and place the 5513 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * into the SouthBrige. Here we cannot rely on looking up the NorthBridge PCI 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ID, while the now ATA-133 capable 5513 still has the same PCI ID. 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Fortunately the 5513 can be 'unmasked' by fiddling with some config space 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bits, changing its device id to the true one - 5517 for 961 and 5518 for 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 962/963. 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ide.h> 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz#define DRV_NAME "sis5513" 55ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz 5625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi/* registers layout and init values are chipset family dependent */ 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_16 0x01 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_33 0x02 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_66 0x03 611eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi#define ATA_100a 0x04 /* SiS730/SiS550 is ATA100 with ATA66 layout */ 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_100 0x05 631eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi#define ATA_133a 0x06 /* SiS961b with 133 support */ 641eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi#define ATA_133 0x07 /* SiS962/963 */ 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 chipset_family; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Devices supported 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const struct { 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *name; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 host_id; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 chipset_family; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 flags; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} SiSHostChipInfo[] = { 7747d4b9066df023670a61e74565a75293cf15a441David Wang { "SiS968", PCI_DEVICE_ID_SI_968, ATA_133 }, 7847d4b9066df023670a61e74565a75293cf15a441David Wang { "SiS966", PCI_DEVICE_ID_SI_966, ATA_133 }, 7914351f8e573442e2437d4b177fa10075aaefd5c9Aurelien Jarno { "SiS965", PCI_DEVICE_ID_SI_965, ATA_133 }, 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 }, 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 }, 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 }, 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS635", PCI_DEVICE_ID_SI_635, ATA_100 }, 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS633", PCI_DEVICE_ID_SI_633, ATA_100 }, 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a }, 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS550", PCI_DEVICE_ID_SI_550, ATA_100a }, 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS640", PCI_DEVICE_ID_SI_640, ATA_66 }, 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS630", PCI_DEVICE_ID_SI_630, ATA_66 }, 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS620", PCI_DEVICE_ID_SI_620, ATA_66 }, 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS540", PCI_DEVICE_ID_SI_540, ATA_66 }, 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS530", PCI_DEVICE_ID_SI_530, ATA_66 }, 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5600", PCI_DEVICE_ID_SI_5600, ATA_33 }, 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5598", PCI_DEVICE_ID_SI_5598, ATA_33 }, 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5597", PCI_DEVICE_ID_SI_5597, ATA_33 }, 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5591/2", PCI_DEVICE_ID_SI_5591, ATA_33 }, 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5582", PCI_DEVICE_ID_SI_5582, ATA_33 }, 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5581", PCI_DEVICE_ID_SI_5581, ATA_33 }, 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5596", PCI_DEVICE_ID_SI_5596, ATA_16 }, 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5571", PCI_DEVICE_ID_SI_5571, ATA_16 }, 104d266ab88938e49aa95f1965ee020df1b1d4c5761Alan Cox { "SiS5517", PCI_DEVICE_ID_SI_5517, ATA_16 }, 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS551x", PCI_DEVICE_ID_SI_5511, ATA_16 }, 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Cycle time bits and values vary across chip dma capabilities 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds These three arrays hold the register layout and the values to set. 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */ 1131eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchistatic u8 cycle_time_offset[] = { 0, 0, 5, 4, 4, 0, 0 }; 1141eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchistatic u8 cycle_time_range[] = { 0, 0, 2, 3, 3, 4, 4 }; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { 1161eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ 1171eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ 1181eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 3, 2, 1, 0, 0, 0, 0 }, /* ATA_33 */ 1191eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 7, 5, 3, 2, 1, 0, 0 }, /* ATA_66 */ 1201eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 7, 5, 3, 2, 1, 0, 0 }, /* ATA_100a (730 specific), 1211eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi different cycle_time range and offset */ 1221eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 11, 7, 5, 4, 2, 1, 0 }, /* ATA_100 */ 1231eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133a (earliest 691 southbridges) */ 1241eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133 */ 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* CRC Valid Setup Time vary across IDE clock setting 33/66/100/133 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds See SiS962 data sheet for more detail */ 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 cvs_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { 1291eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ 1301eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */ 1311eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 2, 1, 1, 0, 0, 0, 0 }, 1321eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 4, 3, 2, 1, 0, 0, 0 }, 1331eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 4, 3, 2, 1, 0, 0, 0 }, 1341eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 6, 4, 3, 1, 1, 1, 0 }, 1351eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 9, 6, 4, 2, 2, 2, 2 }, 1361eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 9, 6, 4, 2, 2, 2, 2 }, 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Initialize time, Active time, Recovery time vary across 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IDE clock settings. These 3 arrays hold the register value 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for PIO0/1/2/3/4 and DMA0/1/2 mode in order */ 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 ini_time_value[][8] = { 1421eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0, 0 }, 1431eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0, 0 }, 1441eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 2, 1, 0, 0, 0, 1, 0, 0 }, 1451eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 4, 3, 1, 1, 1, 3, 1, 1 }, 1461eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 4, 3, 1, 1, 1, 3, 1, 1 }, 1471eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 6, 4, 2, 2, 2, 4, 2, 2 }, 1481eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 9, 6, 3, 3, 3, 6, 3, 3 }, 1491eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 9, 6, 3, 3, 3, 6, 3, 3 }, 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 act_time_value[][8] = { 1521eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0, 0 }, 1531eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0, 0 }, 1541eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 9, 9, 9, 2, 2, 7, 2, 2 }, 1551eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 19, 19, 19, 5, 4, 14, 5, 4 }, 1561eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 19, 19, 19, 5, 4, 14, 5, 4 }, 1571eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 28, 28, 28, 7, 6, 21, 7, 6 }, 1581eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 38, 38, 38, 10, 9, 28, 10, 9 }, 1591eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 38, 38, 38, 10, 9, 28, 10, 9 }, 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 rco_time_value[][8] = { 1621eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0, 0 }, 1631eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 0, 0, 0, 0, 0, 0, 0, 0 }, 1641eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 9, 2, 0, 2, 0, 7, 1, 1 }, 1651eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 19, 5, 1, 5, 2, 16, 3, 2 }, 1661eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 19, 5, 1, 5, 2, 16, 3, 2 }, 1671eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 30, 9, 3, 9, 4, 25, 6, 4 }, 1681eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 40, 12, 4, 12, 5, 34, 12, 5 }, 1691eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi { 40, 12, 4, 12, 5, 34, 12, 5 }, 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Printing configuration 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Used for chipset type printing at boot time */ 1761eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchistatic char *chipset_capability[] = { 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ATA", "ATA 16", 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ATA 33", "ATA 66", 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ATA 100 (1st gen)", "ATA 100 (2nd gen)", 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ATA 133 (1st gen)", "ATA 133 (2nd gen)" 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Configuration functions 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 186c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 187c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewiczstatic u8 sis_ata133_get_base(ide_drive_t *drive) 188c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz{ 18936501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz struct pci_dev *dev = to_pci_dev(drive->hwif->dev); 190c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz u32 reg54 = 0; 191c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 192c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz pci_read_config_dword(dev, 0x54, ®54); 193c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 194c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz return ((reg54 & 0x40000000) ? 0x70 : 0x40) + drive->dn * 4; 195c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz} 196c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 197c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewiczstatic void sis_ata16_program_timings(ide_drive_t *drive, const u8 mode) 198c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz{ 19936501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz struct pci_dev *dev = to_pci_dev(drive->hwif->dev); 200c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz u16 t1 = 0; 201c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz u8 drive_pci = 0x40 + drive->dn * 2; 202c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 203c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz const u16 pio_timings[] = { 0x000, 0x607, 0x404, 0x303, 0x301 }; 204c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz const u16 mwdma_timings[] = { 0x008, 0x302, 0x301 }; 205c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 206c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz pci_read_config_word(dev, drive_pci, &t1); 207c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 208c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz /* clear active/recovery timings */ 209c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 &= ~0x070f; 210c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz if (mode >= XFER_MW_DMA_0) { 211c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz if (chipset_family > ATA_16) 212c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 &= ~0x8000; /* disable UDMA */ 213c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 |= mwdma_timings[mode - XFER_MW_DMA_0]; 214c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz } else 215c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 |= pio_timings[mode - XFER_PIO_0]; 216c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 217c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz pci_write_config_word(dev, drive_pci, t1); 218c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz} 219c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 220c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewiczstatic void sis_ata100_program_timings(ide_drive_t *drive, const u8 mode) 221c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz{ 22236501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz struct pci_dev *dev = to_pci_dev(drive->hwif->dev); 223c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz u8 t1, drive_pci = 0x40 + drive->dn * 2; 224c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 225c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz /* timing bits: 7:4 active 3:0 recovery */ 226c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz const u8 pio_timings[] = { 0x00, 0x67, 0x44, 0x33, 0x31 }; 227c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz const u8 mwdma_timings[] = { 0x08, 0x32, 0x31 }; 228c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 229c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz if (mode >= XFER_MW_DMA_0) { 230c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz u8 t2 = 0; 231c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 232c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz pci_read_config_byte(dev, drive_pci, &t2); 233c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t2 &= ~0x80; /* disable UDMA */ 234c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz pci_write_config_byte(dev, drive_pci, t2); 235c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 236c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 = mwdma_timings[mode - XFER_MW_DMA_0]; 237c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz } else 238c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 = pio_timings[mode - XFER_PIO_0]; 239c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 240c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz pci_write_config_byte(dev, drive_pci + 1, t1); 241c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz} 242c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 243c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewiczstatic void sis_ata133_program_timings(ide_drive_t *drive, const u8 mode) 244c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz{ 24536501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz struct pci_dev *dev = to_pci_dev(drive->hwif->dev); 246c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz u32 t1 = 0; 247c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz u8 drive_pci = sis_ata133_get_base(drive), clk, idx; 248c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 249c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz pci_read_config_dword(dev, drive_pci, &t1); 250c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 251c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 &= 0xc0c00fff; 252c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz clk = (t1 & 0x08) ? ATA_133 : ATA_100; 253c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz if (mode >= XFER_MW_DMA_0) { 254c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 &= ~0x04; /* disable UDMA */ 255c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz idx = mode - XFER_MW_DMA_0 + 5; 2563dfd6433ff4d037262a4b8bede022e1d4bac06e3Adrian Bunk } else 257c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz idx = mode - XFER_PIO_0; 258c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 |= ini_time_value[clk][idx] << 12; 259c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 |= act_time_value[clk][idx] << 16; 260c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz t1 |= rco_time_value[clk][idx] << 24; 261c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 262c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz pci_write_config_dword(dev, drive_pci, t1); 263c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz} 264c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 265c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewiczstatic void sis_program_timings(ide_drive_t *drive, const u8 mode) 266c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz{ 267c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz if (chipset_family < ATA_100) /* ATA_16/33/66/100a */ 268c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz sis_ata16_program_timings(drive, mode); 269c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz else if (chipset_family < ATA_133) /* ATA_100/133a */ 270c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz sis_ata100_program_timings(drive, mode); 271c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz else /* ATA_133 */ 272c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz sis_ata133_program_timings(drive, mode); 273c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz} 274c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz 2751eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchistatic void config_drive_art_rwp(ide_drive_t *drive) 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 277898ec223fea2a2df88035e58dbf50f493577e225Bartlomiej Zolnierkiewicz ide_hwif_t *hwif = drive->hwif; 27836501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz struct pci_dev *dev = to_pci_dev(hwif->dev); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 reg4bh = 0; 280d83fca58d3229f3b23a92a72c3428da8faf09940Bartlomiej Zolnierkiewicz u8 rw_prefetch = 0; 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x4b, ®4bh); 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 284e13ee546bb06453939014c7b854e77fb643fd6f1Bartlomiej Zolnierkiewicz rw_prefetch = reg4bh & ~(0x11 << drive->dn); 285e13ee546bb06453939014c7b854e77fb643fd6f1Bartlomiej Zolnierkiewicz 286d83fca58d3229f3b23a92a72c3428da8faf09940Bartlomiej Zolnierkiewicz if (drive->media == ide_disk) 287e13ee546bb06453939014c7b854e77fb643fd6f1Bartlomiej Zolnierkiewicz rw_prefetch |= 0x11 << drive->dn; 288d83fca58d3229f3b23a92a72c3428da8faf09940Bartlomiej Zolnierkiewicz 289e13ee546bb06453939014c7b854e77fb643fd6f1Bartlomiej Zolnierkiewicz if (reg4bh != rw_prefetch) 290e13ee546bb06453939014c7b854e77fb643fd6f1Bartlomiej Zolnierkiewicz pci_write_config_byte(dev, 0x4b, rw_prefetch); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 293e085b3cae85af47eb0a3eda3186bd898310fb322Bartlomiej Zolnierkiewiczstatic void sis_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds config_drive_art_rwp(drive); 296e085b3cae85af47eb0a3eda3186bd898310fb322Bartlomiej Zolnierkiewicz sis_program_timings(drive, drive->pio_mode); 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 299428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewiczstatic void sis_ata133_program_udma_timings(ide_drive_t *drive, const u8 mode) 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 30136501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz struct pci_dev *dev = to_pci_dev(drive->hwif->dev); 302428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz u32 regdw = 0; 303428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz u8 drive_pci = sis_ata133_get_base(drive), clk, idx; 304428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz 305428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz pci_read_config_dword(dev, drive_pci, ®dw); 306428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz 307428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz regdw |= 0x04; 308428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz regdw &= 0xfffff00f; 309428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz /* check if ATA133 enable */ 310428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz clk = (regdw & 0x08) ? ATA_133 : ATA_100; 311428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz idx = mode - XFER_UDMA_0; 312428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz regdw |= cycle_time_value[clk][idx] << 4; 313428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz regdw |= cvs_time_value[clk][idx] << 8; 314428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz 315428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz pci_write_config_dword(dev, drive_pci, regdw); 316428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz} 317428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz 318428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewiczstatic void sis_ata33_program_udma_timings(ide_drive_t *drive, const u8 mode) 319428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz{ 32036501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz struct pci_dev *dev = to_pci_dev(drive->hwif->dev); 321428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz u8 drive_pci = 0x40 + drive->dn * 2, reg = 0, i = chipset_family; 322428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz 323428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz pci_read_config_byte(dev, drive_pci + 1, ®); 324428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz 325428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz /* force the UDMA bit on if we want to use UDMA */ 326428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz reg |= 0x80; 327428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz /* clean reg cycle time bits */ 328428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz reg &= ~((0xff >> (8 - cycle_time_range[i])) << cycle_time_offset[i]); 329428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz /* set reg cycle time bits */ 330428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz reg |= cycle_time_value[i][mode - XFER_UDMA_0] << cycle_time_offset[i]; 331428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz 332428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz pci_write_config_byte(dev, drive_pci + 1, reg); 333428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz} 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 335428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewiczstatic void sis_program_udma_timings(ide_drive_t *drive, const u8 mode) 336428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz{ 337428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz if (chipset_family >= ATA_133) /* ATA_133 */ 338428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz sis_ata133_program_udma_timings(drive, mode); 339428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz else /* ATA_33/66/100a/100/133a */ 340428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz sis_ata33_program_udma_timings(drive, mode); 341428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz} 342428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz 3438776168ca2151850164af1de5565d01f7b8b2c53Bartlomiej Zolnierkiewiczstatic void sis_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) 344428c6440ef933a3d9df5adfeb2cbb3ea7ebb6a68Bartlomiej Zolnierkiewicz{ 3458776168ca2151850164af1de5565d01f7b8b2c53Bartlomiej Zolnierkiewicz const u8 speed = drive->dma_mode; 3468776168ca2151850164af1de5565d01f7b8b2c53Bartlomiej Zolnierkiewicz 3474db90a145292327b95b03f6dcd3352327235cc36Bartlomiej Zolnierkiewicz if (speed >= XFER_UDMA_0) 3484db90a145292327b95b03f6dcd3352327235cc36Bartlomiej Zolnierkiewicz sis_program_udma_timings(drive, speed); 3494db90a145292327b95b03f6dcd3352327235cc36Bartlomiej Zolnierkiewicz else 3504db90a145292327b95b03f6dcd3352327235cc36Bartlomiej Zolnierkiewicz sis_program_timings(drive, speed); 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 353ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewiczstatic u8 sis_ata133_udma_filter(ide_drive_t *drive) 3543160d5416f39da9d9221fec7cb9d64399b706bbcBartlomiej Zolnierkiewicz{ 35536501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz struct pci_dev *dev = to_pci_dev(drive->hwif->dev); 356c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz u32 regdw = 0; 357c77a89cd98d99819f23a4a08e5e17ee1f13f6e4dBartlomiej Zolnierkiewicz u8 drive_pci = sis_ata133_get_base(drive); 3583160d5416f39da9d9221fec7cb9d64399b706bbcBartlomiej Zolnierkiewicz 3593160d5416f39da9d9221fec7cb9d64399b706bbcBartlomiej Zolnierkiewicz pci_read_config_dword(dev, drive_pci, ®dw); 3603160d5416f39da9d9221fec7cb9d64399b706bbcBartlomiej Zolnierkiewicz 3613160d5416f39da9d9221fec7cb9d64399b706bbcBartlomiej Zolnierkiewicz /* if ATA133 disable, we should not set speed above UDMA5 */ 3623160d5416f39da9d9221fec7cb9d64399b706bbcBartlomiej Zolnierkiewicz return (regdw & 0x08) ? ATA_UDMA6 : ATA_UDMA5; 3633160d5416f39da9d9221fec7cb9d64399b706bbcBartlomiej Zolnierkiewicz} 3643160d5416f39da9d9221fec7cb9d64399b706bbcBartlomiej Zolnierkiewicz 365fe31edc8a3b6081f3580c9ae4c5c61103f3412a5Greg Kroah-Hartmanstatic int sis_find_family(struct pci_dev *dev) 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *host; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 0; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = 0; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) { 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37440cddf2cbd02aa830254afcd5a1a21b4e882a189Alan Cox host = pci_get_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL); 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!host) 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = SiSHostChipInfo[i].chipset_family; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Special case for SiS630 : 630S/ET is ATA_100a */ 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) { 38344c10138fd4bbc4b6d6bff0873c24902f2a9da65Auke Kok if (host->revision >= 0x30) 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = ATA_100a; 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 38640cddf2cbd02aa830254afcd5a1a21b4e882a189Alan Cox pci_dev_put(host); 3871eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi 388ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz printk(KERN_INFO DRV_NAME " %s: %s %s controller\n", 38928cfd8af52a9ed4e5bd1751ea6bc0b8c870f68ecBartlomiej Zolnierkiewicz pci_name(dev), SiSHostChipInfo[i].name, 39028cfd8af52a9ed4e5bd1751ea6bc0b8c870f68ecBartlomiej Zolnierkiewicz chipset_capability[chipset_family]); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!chipset_family) { /* Belongs to pci-quirks */ 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 idemisc; 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 trueid; 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable ID masking and register remapping */ 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_dword(dev, 0x54, &idemisc); 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_dword(dev, 0x54, (idemisc & 0x7fffffff)); 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_dword(dev, 0x54, idemisc); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (trueid == 0x5518) { 405ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz printk(KERN_INFO DRV_NAME " %s: SiS 962/963 MuTIOL IDE UDMA133 controller\n", 40628cfd8af52a9ed4e5bd1751ea6bc0b8c870f68ecBartlomiej Zolnierkiewicz pci_name(dev)); 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = ATA_133; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* Check for 5513 compatibility mapping 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We must use this, else the port enabled code will fail, 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as it expects the enablebits at 0x4a. 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((idemisc & 0x40000000) == 0) { 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_dword(dev, 0x54, idemisc | 0x40000000); 415ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz printk(KERN_INFO DRV_NAME " %s: Switching to 5513 register mapping\n", 41628cfd8af52a9ed4e5bd1751ea6bc0b8c870f68ecBartlomiej Zolnierkiewicz pci_name(dev)); 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!chipset_family) { /* Belongs to pci-quirks */ 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *lpc_bridge; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 trueid; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 prefctl; 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 idecfg; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x4a, &idecfg); 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, 0x4a, idecfg | 0x10); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, 0x4a, idecfg); 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (trueid == 0x5517) { /* SiS 961/961B */ 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 435b1489009963b8c5132f2ffe23483e811d9ae5607Alan Cox lpc_bridge = pci_get_slot(dev->bus, 0x10); /* Bus 0, Dev 2, Fn 0 */ 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x49, &prefctl); 437b1489009963b8c5132f2ffe23483e811d9ae5607Alan Cox pci_dev_put(lpc_bridge); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43944c10138fd4bbc4b6d6bff0873c24902f2a9da65Auke Kok if (lpc_bridge->revision == 0x10 && (prefctl & 0x80)) { 440ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz printk(KERN_INFO DRV_NAME " %s: SiS 961B MuTIOL IDE UDMA133 controller\n", 44128cfd8af52a9ed4e5bd1751ea6bc0b8c870f68ecBartlomiej Zolnierkiewicz pci_name(dev)); 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = ATA_133a; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 444ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz printk(KERN_INFO DRV_NAME " %s: SiS 961 MuTIOL IDE UDMA100 controller\n", 44528cfd8af52a9ed4e5bd1751ea6bc0b8c870f68ecBartlomiej Zolnierkiewicz pci_name(dev)); 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = ATA_100; 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4514764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz return chipset_family; 4524764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz} 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4542ed0ef543ae3f3ea4f8bd0433fb1fed22625a309Bartlomiej Zolnierkiewiczstatic int init_chipset_sis5513(struct pci_dev *dev) 4554764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz{ 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make general config ops here 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1/ tell IDE channels to operate in Compatibility mode only 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2/ tell old chips to allow per drive IDE timings */ 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4601eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi u8 reg; 4611eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi u16 regw; 4621eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi 4631eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi switch (chipset_family) { 4641eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi case ATA_133: 4651eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi /* SiS962 operation mode */ 4661eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_read_config_word(dev, 0x50, ®w); 4671eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi if (regw & 0x08) 4681eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_write_config_word(dev, 0x50, regw&0xfff7); 4691eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_read_config_word(dev, 0x52, ®w); 4701eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi if (regw & 0x08) 4711eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_write_config_word(dev, 0x52, regw&0xfff7); 4721eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi break; 4731eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi case ATA_133a: 4741eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi case ATA_100: 4751eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi /* Fixup latency */ 4761eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80); 4771eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi /* Set compatibility bit */ 4781eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_read_config_byte(dev, 0x49, ®); 4791eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi if (!(reg & 0x01)) 4801eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_write_config_byte(dev, 0x49, reg|0x01); 4811eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi break; 4821eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi case ATA_100a: 4831eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi case ATA_66: 4841eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi /* Fixup latency */ 4851eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10); 4861eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi 4871eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi /* On ATA_66 chips the bit was elsewhere */ 4881eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_read_config_byte(dev, 0x52, ®); 4891eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi if (!(reg & 0x04)) 4901eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_write_config_byte(dev, 0x52, reg|0x04); 4911eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi break; 4921eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi case ATA_33: 4931eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi /* On ATA_33 we didn't have a single bit to set */ 4941eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_read_config_byte(dev, 0x09, ®); 4951eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi if ((reg & 0x0f) != 0x00) 4961eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_write_config_byte(dev, 0x09, reg&0xf0); 4971eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi case ATA_16: 4981eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi /* force per drive recovery and active timings 4991eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi needed on ATA_33 and below chips */ 5001eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_read_config_byte(dev, 0x52, ®); 5011eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi if (!(reg & 0x08)) 5021eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi pci_write_config_byte(dev, 0x52, reg|0x08); 5031eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi break; 5041eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi } 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 509f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewiczstruct sis_laptop { 510f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz u16 device; 511f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz u16 subvendor; 512f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz u16 subdevice; 513f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz}; 514f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz 515f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewiczstatic const struct sis_laptop sis_laptop[] = { 516f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz /* devid, subvendor, subdev */ 517f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ 5181955f6814fb58ffa06af4873a445307d60b23fb1David Lamparter { 0x5513, 0x1734, 0x105f }, /* FSC Amilo A1630 */ 519a1d85864d30181a71243193ed01d322dc0618dc6Gabriel Craciunescu { 0x5513, 0x1071, 0x8640 }, /* EasyNote K5305 */ 520f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz /* end marker */ 521f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz { 0, } 522f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz}; 523f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz 524f454cbe8cd38b6d447e74ddaf012017fea42717eBartlomiej Zolnierkiewiczstatic u8 sis_cable_detect(ide_hwif_t *hwif) 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 52636501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz struct pci_dev *pdev = to_pci_dev(hwif->dev); 527f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz const struct sis_laptop *lap = &sis_laptop[0]; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 ata66 = 0; 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 530f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz while (lap->device) { 531f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz if (lap->device == pdev->device && 532f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz lap->subvendor == pdev->subsystem_vendor && 533f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz lap->subdevice == pdev->subsystem_device) 534f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz return ATA_CBL_PATA40_SHORT; 535f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz lap++; 536f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz } 537f2befd9e80b39a5aa54d65cf59b6a5feb9a8117eBartlomiej Zolnierkiewicz 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family >= ATA_133) { 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 regw = 0; 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 reg_addr = hwif->channel ? 0x52: 0x50; 54136501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz pci_read_config_word(pdev, reg_addr, ®w); 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ata66 = (regw & 0x8000) ? 0 : 1; 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (chipset_family >= ATA_66) { 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 reg48h = 0; 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 mask = hwif->channel ? 0x20 : 0x10; 54636501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz pci_read_config_byte(pdev, 0x48, ®48h); 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ata66 = (reg48h & mask) ? 0 : 1; 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 54949521f97ccd3c2bf6e71a91cea8fe65d170fa4fbBartlomiej Zolnierkiewicz 55049521f97ccd3c2bf6e71a91cea8fe65d170fa4fbBartlomiej Zolnierkiewicz return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 553ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewiczstatic const struct ide_port_ops sis_port_ops = { 554ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz .set_pio_mode = sis_set_pio_mode, 555ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz .set_dma_mode = sis_set_dma_mode, 556ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz .cable_detect = sis_cable_detect, 557ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz}; 5583160d5416f39da9d9221fec7cb9d64399b706bbcBartlomiej Zolnierkiewicz 559ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewiczstatic const struct ide_port_ops sis_ata133_port_ops = { 560ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz .set_pio_mode = sis_set_pio_mode, 561ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz .set_dma_mode = sis_set_dma_mode, 562ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz .udma_filter = sis_ata133_udma_filter, 563ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz .cable_detect = sis_cable_detect, 564ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz}; 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 566fe31edc8a3b6081f3580c9ae4c5c61103f3412a5Greg Kroah-Hartmanstatic const struct ide_port_info sis5513_chipset = { 567ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz .name = DRV_NAME, 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init_chipset = init_chipset_sis5513, 5691eb3c2ee1d20cc03d538232c05b8f320de6b1401Paolo Ciarrocchi .enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} }, 5702467922a560bb7e6eb4635435760ad0a2197ffccBartlomiej Zolnierkiewicz .host_flags = IDE_HFLAG_NO_AUTODMA, 5714099d14322149c7a467e4997b87be4ba8eb78697Bartlomiej Zolnierkiewicz .pio_mask = ATA_PIO4, 5725f8b6c34854a966fe5eb7241fde0419d47d5d408Bartlomiej Zolnierkiewicz .mwdma_mask = ATA_MWDMA2, 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 575fe31edc8a3b6081f3580c9ae4c5c61103f3412a5Greg Kroah-Hartmanstatic int sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5774764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz struct ide_port_info d = sis5513_chipset; 5784764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f }; 579cd18f69f845dc8c769f0ef65046b7a113b8aba87Bartlomiej Zolnierkiewicz int rc; 580cd18f69f845dc8c769f0ef65046b7a113b8aba87Bartlomiej Zolnierkiewicz 581cd18f69f845dc8c769f0ef65046b7a113b8aba87Bartlomiej Zolnierkiewicz rc = pci_enable_device(dev); 582cd18f69f845dc8c769f0ef65046b7a113b8aba87Bartlomiej Zolnierkiewicz if (rc) 583cd18f69f845dc8c769f0ef65046b7a113b8aba87Bartlomiej Zolnierkiewicz return rc; 5844764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz 5854764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz if (sis_find_family(dev) == 0) 5864764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz return -ENOTSUPP; 5874764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz 588ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz if (chipset_family >= ATA_133) 589ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz d.port_ops = &sis_ata133_port_ops; 590ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz else 591ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz d.port_ops = &sis_port_ops; 592ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz 5934764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz d.udma_mask = udma_rates[chipset_family]; 5944764b68405ac918e9ac9939b1a2d1469102e5af7Bartlomiej Zolnierkiewicz 5956cdf6eb357c2681596b7b1672b92396ba82333d4Bartlomiej Zolnierkiewicz return ide_pci_init_one(dev, &d, NULL); 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 598fe31edc8a3b6081f3580c9ae4c5c61103f3412a5Greg Kroah-Hartmanstatic void sis5513_remove(struct pci_dev *dev) 5991ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewicz{ 6001ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewicz ide_pci_remove(dev); 6011ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewicz pci_disable_device(dev); 6021ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewicz} 6031ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewicz 6049cbcc5e3c5d2d0355fed22d00762fd764c81a383Bartlomiej Zolnierkiewiczstatic const struct pci_device_id sis5513_pci_tbl[] = { 6059cbcc5e3c5d2d0355fed22d00762fd764c81a383Bartlomiej Zolnierkiewicz { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_5513), 0 }, 6069cbcc5e3c5d2d0355fed22d00762fd764c81a383Bartlomiej Zolnierkiewicz { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_5518), 0 }, 6079cbcc5e3c5d2d0355fed22d00762fd764c81a383Bartlomiej Zolnierkiewicz { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_1180), 0 }, 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0, }, 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DEVICE_TABLE(pci, sis5513_pci_tbl); 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 612a9ab09e26055a76295548ca36ec00de2f4367d32Bartlomiej Zolnierkiewiczstatic struct pci_driver sis5513_pci_driver = { 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "SIS_IDE", 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .id_table = sis5513_pci_tbl, 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .probe = sis5513_init_one, 616fe31edc8a3b6081f3580c9ae4c5c61103f3412a5Greg Kroah-Hartman .remove = sis5513_remove, 617feb22b7f8e62b1b987a3a1dbad95af767a1df832Bartlomiej Zolnierkiewicz .suspend = ide_pci_suspend, 618feb22b7f8e62b1b987a3a1dbad95af767a1df832Bartlomiej Zolnierkiewicz .resume = ide_pci_resume, 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 62182ab1eeceba6705cd5a8815c48eb03af1dada744Bartlomiej Zolnierkiewiczstatic int __init sis5513_ide_init(void) 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 623a9ab09e26055a76295548ca36ec00de2f4367d32Bartlomiej Zolnierkiewicz return ide_pci_register_driver(&sis5513_pci_driver); 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6261ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewiczstatic void __exit sis5513_ide_exit(void) 6271ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewicz{ 628a9ab09e26055a76295548ca36ec00de2f4367d32Bartlomiej Zolnierkiewicz pci_unregister_driver(&sis5513_pci_driver); 6291ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewicz} 6301ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewicz 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(sis5513_ide_init); 6321ceb906b4062954e92295191402e9214345ee0e9Bartlomiej Zolnierkiewiczmodule_exit(sis5513_ide_exit); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik"); 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("PCI driver module for SIS IDE"); 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 637