diff options
author | sos <sos@FreeBSD.org> | 2005-10-12 20:00:26 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2005-10-12 20:00:26 +0000 |
commit | e52c6023e63fb6a76b24587c9f4b384326a7c4e9 (patch) | |
tree | 26be3138a55d4fe1bd79beca46297c27d45bb6b0 /sys/dev/ata | |
parent | d6130a47038460d2093bdc0fcdadd546393cc823 (diff) | |
download | FreeBSD-src-e52c6023e63fb6a76b24587c9f4b384326a7c4e9.zip FreeBSD-src-e52c6023e63fb6a76b24587c9f4b384326a7c4e9.tar.gz |
Add support for the ATI IXP[234]00 series chipsets.
HW donated by: sentex
Diffstat (limited to 'sys/dev/ata')
-rw-r--r-- | sys/dev/ata/ata-chipset.c | 113 | ||||
-rw-r--r-- | sys/dev/ata/ata-pci.c | 4 | ||||
-rw-r--r-- | sys/dev/ata/ata-pci.h | 9 | ||||
-rw-r--r-- | sys/dev/ata/ata-raid.c | 1 |
4 files changed, 126 insertions, 1 deletions
diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c index a5af06e..e800f2d 100644 --- a/sys/dev/ata/ata-chipset.c +++ b/sys/dev/ata/ata-chipset.c @@ -77,6 +77,8 @@ static int ata_ali_sata_allocate(device_t dev); static void ata_ali_reset(device_t dev); static void ata_ali_setmode(device_t dev, int mode); static int ata_amd_chipinit(device_t dev); +static int ata_ati_chipinit(device_t dev); +static void ata_ati_setmode(device_t dev, int mode); static int ata_cyrix_chipinit(device_t dev); static void ata_cyrix_setmode(device_t dev, int mode); static int ata_cypress_chipinit(device_t dev); @@ -1111,6 +1113,115 @@ ata_amd_chipinit(device_t dev) /* + * ATI chipset support functions + */ +int +ata_ati_ident(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + struct ata_chip_id *idx; + static struct ata_chip_id ids[] = + {{ ATA_ATI_IXP200, 0x00, 0, 0, ATA_UDMA5, "ATI IXP200" }, + { ATA_ATI_IXP300, 0x00, 0, 0, ATA_UDMA6, "ATI IXP300" }, + { ATA_ATI_IXP400, 0x00, 0, 0, ATA_UDMA6, "ATI IXP400" }, + { ATA_ATI_IXP300_S1, 0x00, SIIMEMIO, 0, ATA_SA150, "ATI IXP300" }, + { ATA_ATI_IXP400_S1, 0x00, SIIMEMIO, 0, ATA_SA150, "ATI IXP400" }, + { ATA_ATI_IXP400_S2, 0x00, SIIMEMIO, 0, ATA_SA150, "ATI IXP400" }, + { 0, 0, 0, 0, 0, 0}}; + char buffer[64]; + + if (!(idx = ata_match_chip(dev, ids))) + return ENXIO; + + sprintf(buffer, "%s %s controller", idx->text, ata_mode2str(idx->max_dma)); + device_set_desc_copy(dev, buffer); + ctlr->chip = idx; + + /* the ATI SATA controller is actually a SiI 3112 controller*/ + if (ctlr->chip->cfg1 & SIIMEMIO) + ctlr->chipinit = ata_sii_chipinit; + else + ctlr->chipinit = ata_ati_chipinit; + return 0; +} + +static int +ata_ati_chipinit(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + + if (ata_setup_interrupt(dev)) + return ENXIO; + + ctlr->setmode = ata_ati_setmode; + return 0; +} + +static void +ata_ati_setmode(device_t dev, int mode) +{ + device_t gparent = GRANDPARENT(dev); + struct ata_pci_controller *ctlr = device_get_softc(gparent); + struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + struct ata_device *atadev = device_get_softc(dev); + int devno = (ch->unit << 1) + ATA_DEV(atadev->unit); + int offset = (devno ^ 0x01) << 3; + int error; + u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; + u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 }; + + mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); + + mode = ata_check_80pin(dev, mode); + + error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); + + if (bootverbose) + device_printf(dev, "%ssetting %s on %s chip\n", + (error) ? "FAILURE " : "", + ata_mode2str(mode), ctlr->chip->text); + if (!error) { + if (mode >= ATA_UDMA0) { + pci_write_config(gparent, 0x56, + (pci_read_config(gparent, 0x56, 2) & + ~(0xf << (devno << 2))) | + ((mode & ATA_MODE_MASK) << (devno << 2)), 2); + pci_write_config(gparent, 0x54, + pci_read_config(gparent, 0x54, 1) | + (0x01 << devno), 1); + pci_write_config(gparent, 0x44, + (pci_read_config(gparent, 0x44, 4) & + ~(0xff << offset)) | + (dmatimings[2] << offset), 4); + } + else if (mode >= ATA_WDMA0) { + pci_write_config(gparent, 0x54, + pci_read_config(gparent, 0x54, 1) & + ~(0x01 << devno), 1); + pci_write_config(gparent, 0x44, + (pci_read_config(gparent, 0x44, 4) & + ~(0xff << offset)) | + (dmatimings[mode & ATA_MODE_MASK] << offset), 4); + } + else + pci_write_config(gparent, 0x54, + pci_read_config(gparent, 0x54, 1) & + ~(0x01 << devno), 1); + + pci_write_config(gparent, 0x4a, + (pci_read_config(gparent, 0x4a, 2) & + ~(0xf << (devno << 2))) | + (((mode - ATA_PIO0) & ATA_MODE_MASK) << (devno<<2)),2); + pci_write_config(gparent, 0x40, + (pci_read_config(gparent, 0x40, 4) & + ~(0xff << offset)) | + (piotimings[ata_mode2idx(mode)] << offset), 4); + atadev->mode = mode; + } +} + +/* * Cyrix chipset support functions */ int @@ -3260,7 +3371,7 @@ ata_serverworks_setmode(device_t dev, int mode) pci_write_config(gparent, 0x44, (pci_read_config(gparent, 0x44, 4) & ~(0xff << offset)) | - (dmatimings[mode & ATA_MODE_MASK] << offset),4); + (dmatimings[mode & ATA_MODE_MASK] << offset), 4); } else pci_write_config(gparent, 0x54, diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index 0222ef5..43a0a0a 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -90,6 +90,10 @@ ata_pci_probe(device_t dev) if (!ata_amd_ident(dev)) return 0; break; + case ATA_ATI_ID: + if (!ata_ati_ident(dev)) + return 0; + break; case ATA_CYRIX_ID: if (!ata_cyrix_ident(dev)) return 0; diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index 99a1fb1..b09afcb 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -97,6 +97,14 @@ struct ata_connect_task { #define ATA_ALI_5288 0x528810b9 #define ATA_ALI_5289 0x528910b9 +#define ATA_ATI_ID 0x1002 +#define ATA_ATI_IXP200 0x43491002 +#define ATA_ATI_IXP300 0x43691002 +#define ATA_ATI_IXP400 0x43761002 +#define ATA_ATI_IXP300_S1 0x436e1002 +#define ATA_ATI_IXP400_S1 0x43791002 +#define ATA_ATI_IXP400_S2 0x437a1002 + #define ATA_CENATEK_ID 0x16ca #define ATA_CENATEK_ROCKET 0x000116ca @@ -373,6 +381,7 @@ int ata_generic_ident(device_t); int ata_acard_ident(device_t); int ata_ali_ident(device_t); int ata_amd_ident(device_t); +int ata_ati_ident(device_t); int ata_cyrix_ident(device_t); int ata_cypress_ident(device_t); int ata_highpoint_ident(device_t); diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index f0b9eb8..ce08bd8 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -1225,6 +1225,7 @@ ata_raid_read_metadata(device_t subdisk) return 0; break; + case ATA_ATI_ID: case ATA_SILICON_IMAGE_ID: if (ata_raid_sii_read_meta(subdisk, ata_raid_arrays)) return 0; |