From 09cda20f320a0f4a9163372573b18604e0c4ae85 Mon Sep 17 00:00:00 2001 From: sos Date: Sun, 6 Aug 2000 19:51:58 +0000 Subject: [PATCH] Add experimental code for ATA100 support on: Promise Ultra100 / Fasttrak100 HighPoint HPT370 controllers (fx Abit KA7-100 onboard ctrl, Abit HotRod 100) Intel ICH2 (Intel 815E based motherboards) So far I can read >90MB/s on the Promise and the HPT370. I can write >64MB/s on the promise and >50MB/s on the HPT370 so it seems writing is still done in ATA66 mode :( The ICH2 support is untested as of yet... --- sys/dev/ata/ata-all.c | 56 ++++++++++-- sys/dev/ata/ata-all.h | 1 + sys/dev/ata/ata-dma.c | 208 ++++++++++++++++++++++++++++++------------ 3 files changed, 200 insertions(+), 65 deletions(-) diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 9d378796932a..a699be4050fd 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -254,11 +254,14 @@ ata_pci_match(device_t dev) case 0x71998086: return "Intel PIIX4 ATA33 controller"; + case 0x24218086: + return "Intel ICH0 ATA33 controller"; + case 0x24118086: return "Intel ICH ATA66 controller"; - case 0x24218086: - return "Intel ICH0 ATA33 controller"; + case 0x244b8086: + return "Intel ICH2 ATA100 controller"; case 0x522910b9: return "AcerLabs Aladdin ATA33 controller"; @@ -294,8 +297,22 @@ ata_pci_match(device_t dev) case 0x4d38105a: return "Promise ATA66 controller"; + case 0x4d30105a: + return "Promise ATA100 controller"; + case 0x00041103: - return "HighPoint HPT366 ATA66 controller"; + switch (pci_get_revid(dev)) { + case 0x00: + case 0x01: + return "HighPoint HPT366 ATA66 controller"; + case 0x02: + return "HighPoint HPT368 ATA66 controller"; + case 0x03: + case 0x04: + return "HighPoint HPT370 ATA100 controller"; + default: + return "Unknown revision HighPoint ATA controller"; + } /* unsupported but known chipsets, generic DMA only */ case 0x10001042: @@ -379,8 +396,9 @@ ata_pci_attach(device_t dev) device_printf(dev, "Busmastering DMA not enabled\n"); } else { - if (type == 0x4d33105a || type == 0x4d38105a || type == 0x00041103) { - /* Promise and HPT366 controllers support busmastering DMA */ + if (type == 0x4d33105a || type == 0x4d38105a || + type == 0x4d30105a || type == 0x00041103) { + /* Promise and HighPoint controllers support busmastering DMA */ rid = 0x20; sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); @@ -398,6 +416,7 @@ ata_pci_attach(device_t dev) break; case 0x4d38105a: /* Promise 66's need their clock changed */ + case 0x4d30105a: /* Promise 100 too */ outb(rman_get_start(sc->bmio) + 0x11, inb(rman_get_start(sc->bmio) + 0x11) | 0x0a); /* FALLTHROUGH */ @@ -407,8 +426,25 @@ ata_pci_attach(device_t dev) inb(rman_get_start(sc->bmio) + 0x1f) | 0x01); break; - case 0x00041103: /* HPT366 turn of fast interrupt prediction */ - pci_write_config(dev, 0x51, (pci_read_config(dev, 0x51, 1) & ~0x80), 1); + case 0x00041103: /* HighPoint's need to turn off interrupt prediction */ + switch (pci_get_revid(dev)) { + case 0x00: + case 0x01: + pci_write_config(dev, 0x51, + (pci_read_config(dev, 0x51, 1) & ~0x80), 1); + break; + + case 0x02: + case 0x03: + case 0x04: + pci_write_config(dev, 0x51, + (pci_read_config(dev, 0x51, 1) & ~0x02), 1); + pci_write_config(dev, 0x55, + (pci_read_config(dev, 0x55, 1) & ~0x02), 1); + pci_write_config(dev, 0x5a, + (pci_read_config(dev, 0x5a, 1) & ~0x10), 1); + + } break; case 0x05711106: @@ -1086,7 +1122,7 @@ ata_intr(void *data) */ switch (scp->chiptype) { #if NPCI > 0 - case 0x00041103: /* HighPoint HPT366 */ + case 0x00041103: /* HighPoint HPT366/368/370 */ if (!((dmastat = ata_dmastatus(scp)) & ATA_BMSTAT_INTERRUPT)) return; outb(scp->bmaddr + ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT); @@ -1094,6 +1130,7 @@ ata_intr(void *data) case 0x4d33105a: /* Promise 33's */ case 0x4d38105a: /* Promise 66's */ + case 0x4d30105a: /* Promise 100's */ { struct ata_pci_softc *sc=device_get_softc(device_get_parent(scp->dev)); @@ -1463,6 +1500,7 @@ ata_mode2str(int32_t mode) case ATA_WDMA2: return "WDMA2"; case ATA_UDMA2: return "UDMA33"; case ATA_UDMA4: return "UDMA66"; + case ATA_UDMA5: return "UDMA100"; case ATA_DMA: return "BIOSDMA"; default: return "???"; } @@ -1515,6 +1553,8 @@ int ata_umode(struct ata_params *ap) { if (ap->atavalid & ATA_FLAG_88) { + if (ap->udmamodes & 0x20) + return 5; if (ap->udmamodes & 0x10) return 4; if (ap->udmamodes & 0x08) diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 14a3d971882e..811b98966ef8 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -279,6 +279,7 @@ struct ata_softc { #define ATA_WDMA2 0x22 #define ATA_UDMA2 0x42 #define ATA_UDMA4 0x44 +#define ATA_UDMA5 0x45 int32_t flags; /* controller flags */ #define ATA_DMA_ACTIVE 0x01 diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index 908a3768dd7a..1d82ee7c949a 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -48,7 +48,7 @@ /* prototypes */ static void promise_timing(struct ata_softc *, int32_t, int32_t); -static void hpt366_timing(struct ata_softc *, int32_t, int32_t); +static void hpt_timing(struct ata_softc *, int32_t, int32_t); /* misc defines */ #ifdef __alpha__ @@ -61,8 +61,8 @@ ata_dmainit(struct ata_softc *scp, int32_t device, int32_t apiomode, int32_t wdmamode, int32_t udmamode) { device_t parent = device_get_parent(scp->dev); - int32_t devno = (scp->unit << 1) + ATA_DEV(device); - int32_t error; + int devno = (scp->unit << 1) + ATA_DEV(device); + int error; /* set our most pessimistic default mode */ scp->mode[ATA_DEV(device)] = ATA_PIO; @@ -101,6 +101,39 @@ ata_dmainit(struct ata_softc *scp, int32_t device, switch (scp->chiptype) { + case 0x244b8086: /* Intel ICH2 */ + if (udmamode >= 5) { + int32_t mask48, new48; + int16_t word54; + + word54 = pci_read_config(parent, 0x54, 2); + if (word54 & (0x10 << devno)) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, + ATA_UDMA5, ATA_C_F_SETXFER,ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, + "%s setting up UDMA5 mode on ICH2 chip\n", + (error) ? "failed" : "success"); + if (!error) { + mask48 = (1 << devno) + (3 << (16 + (devno << 2))); + new48 = (1 << devno) + (1 << (16 + (devno << 2))); + pci_write_config(parent, 0x48, + (pci_read_config(parent, 0x48, 4) & + ~mask48) | new48, 4); + pci_write_config(parent, 0x54, word54 & ~(0x1000<mode[ATA_DEV(device)] = ATA_UDMA5; + return; + } + } + } + if (udmamode >= 4) { + int16_t word54; + + word54 = pci_read_config(parent, 0x54, 2); + pci_write_config(parent, 0x54, word54 & ~(0x1000 << devno), 2); + } + /* FALLTHROUGH */ + case 0x24118086: /* Intel ICH */ if (udmamode >= 4) { int32_t mask48, new48; @@ -112,8 +145,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device, ATA_UDMA4, ATA_C_F_SETXFER,ATA_WAIT_READY); if (bootverbose) ata_printf(scp, device, - "%s setting up UDMA4 mode on ICH chip\n", - (error) ? "failed" : "success"); + "%s setting up UDMA4 mode on ICH%s chip\n", + (error) ? "failed" : "success", + (scp->chiptype == 0x244b8086) ? "2" : ""); if (!error) { mask48 = (1 << devno) + (3 << (16 + (devno << 2))); new48 = (1 << devno) + (2 << (16 + (devno << 2))); @@ -126,6 +160,12 @@ ata_dmainit(struct ata_softc *scp, int32_t device, } } } + if (udmamode >= 2) { + int16_t word54; + + word54 = pci_read_config(parent, 0x54, 2); + pci_write_config(parent, 0x54, word54 & ~(1 << devno), 2); + } /* FALLTHROUGH */ case 0x71118086: /* Intel PIIX4 */ @@ -139,8 +179,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device, if (bootverbose) ata_printf(scp, device, "%s setting up UDMA2 mode on %s chip\n", (error) ? "failed" : "success", - (scp->chiptype == 0x24118086) ? "ICH" : - (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4"); + (scp->chiptype == 0x244b8086) ? "ICH2" : + (scp->chiptype == 0x24118086) ? "ICH" : + (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4"); if (!error) { mask48 = (1 << devno) + (3 << (16 + (devno << 2))); new48 = (1 << devno) + (2 << (16 + (devno << 2))); @@ -178,9 +219,10 @@ ata_dmainit(struct ata_softc *scp, int32_t device, if (bootverbose) ata_printf(scp, device, "%s setting up WDMA2 mode on %s chip\n", (error) ? "failed" : "success", - (scp->chiptype == 0x70108086) ? "PIIX3" : + (scp->chiptype == 0x244b8086) ? "ICH2" : (scp->chiptype == 0x24118086) ? "ICH" : - (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4"); + (scp->chiptype == 0x24218086) ? "ICH0" : + (scp->chiptype == 0x70108086) ? "PIIX3":"PIIX4"); if (!error) { if (device == ATA_MASTER) { mask40 = 0x0000330f; @@ -444,12 +486,28 @@ ata_dmainit(struct ata_softc *scp, int32_t device, case 0x4d33105a: /* Promise Ultra33 / FastTrak33 controllers */ case 0x4d38105a: /* Promise Ultra66 / FastTrak66 controllers */ + case 0x4d30105a: /* Promise Ultra100 / FastTrak100 controllers */ /* the Promise can only do DMA on ATA disks not on ATAPI devices */ if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) break; - if (udmamode >=4 && scp->chiptype == 0x4d38105a && + if (udmamode >=5 && scp->chiptype == 0x4d30105a && + !(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, + ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, + "%s setting up UDMA5 mode on Promise chip\n", + (error) ? "failed" : "success"); + if (!error) { + promise_timing(scp, devno, ATA_UDMA5); + scp->mode[ATA_DEV(device)] = ATA_UDMA5; + return; + } + } + if (udmamode >=4 && + (scp->chiptype == 0x4d38105a || scp->chiptype == 0x4d30105a) && !(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); @@ -501,13 +559,29 @@ ata_dmainit(struct ata_softc *scp, int32_t device, scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); return; - case 0x00041103: /* HighPoint HPT366 controller */ + case 0x00041103: /* HighPoint HPT366/368/370 controllers */ /* no ATAPI devices for now */ if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) break; - if (udmamode >=4 && !(pci_read_config(parent, 0x5a, 1) & 0x2)) { + if (udmamode >=5 && pci_get_revid(parent) >= 0x03 && + !(pci_read_config(parent, 0x5a, 1) & (scp->unit ? 0x01 : 0x02))) { + error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, + ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_printf(scp, device, + "%s setting up UDMA5 mode on HPT370 chip\n", + (error) ? "failed" : "success"); + if (!error) { + hpt_timing(scp, devno, ATA_UDMA5); + scp->mode[ATA_DEV(device)] = ATA_UDMA5; + return; + } + } + + if (udmamode >=4 && + !(pci_read_config(parent, 0x5a, 1) & (scp->unit ? 0x01 : 0x02))) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -515,7 +589,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, "%s setting up UDMA4 mode on HPT366 chip\n", (error) ? "failed" : "success"); if (!error) { - hpt366_timing(scp, devno, ATA_UDMA4); + hpt_timing(scp, devno, ATA_UDMA4); scp->mode[ATA_DEV(device)] = ATA_UDMA4; return; } @@ -528,7 +602,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, "%s setting up UDMA2 mode on HPT366 chip\n", (error) ? "failed" : "success"); if (!error) { - hpt366_timing(scp, devno, ATA_UDMA2); + hpt_timing(scp, devno, ATA_UDMA2); scp->mode[ATA_DEV(device)] = ATA_UDMA2; return; } @@ -541,7 +615,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, "%s setting up WDMA2 mode on HPT366 chip\n", (error) ? "failed" : "success"); if (!error) { - hpt366_timing(scp, devno, ATA_WDMA2); + hpt_timing(scp, devno, ATA_WDMA2); scp->mode[ATA_DEV(device)] = ATA_WDMA2; return; } @@ -553,7 +627,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, ata_printf(scp, device, "%s setting up PIO%d mode on HPT366 chip\n", (error) ? "failed" : "success", (apiomode >= 0) ? apiomode : 0); - hpt366_timing(scp, devno, ata_pio2mode(apiomode)); + hpt_timing(scp, devno, ata_pio2mode(apiomode)); scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); return; @@ -607,7 +681,7 @@ ata_dmasetup(struct ata_softc *scp, int32_t device, { struct ata_dmaentry *dmatab; u_int32_t dma_count, dma_base; - int32_t i = 0; + int i = 0; if (((uintptr_t)data & 1) || (count & 1)) return -1; @@ -708,6 +782,7 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode) break; case 0x4d38105a: /* Promise 66's */ + case 0x4d30105a: /* Promise 100's */ switch (mode) { default: case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break; @@ -718,6 +793,7 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode) case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break; case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break; case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; + case ATA_UDMA5: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; } break; } @@ -725,53 +801,71 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode) } static void -hpt366_timing(struct ata_softc *scp, int32_t devno, int32_t mode) +hpt_timing(struct ata_softc *scp, int32_t devno, int32_t mode) { device_t parent = device_get_parent(scp->dev); u_int32_t timing; - switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) { - case 0x85: /* 25Mhz */ + if (pci_get_revid(parent) >= 0x03) { /* HPT370 */ switch (mode) { - case ATA_PIO0: timing = 0xc0d08585; break; - case ATA_PIO1: timing = 0xc0d08572; break; - case ATA_PIO2: timing = 0xc0ca8542; break; - case ATA_PIO3: timing = 0xc0ca8532; break; - case ATA_PIO4: timing = 0xc0ca8521; break; - case ATA_WDMA2: timing = 0xa0ca8521; break; - case ATA_UDMA2: timing = 0x90cf8521; break; - case ATA_UDMA4: timing = 0x90c98521; break; - default: timing = 0x01208585; - } - break; - default: - case 0xa7: /* 33MHz */ - switch (mode) { - case ATA_PIO0: timing = 0xc0d0a7aa; break; - case ATA_PIO1: timing = 0xc0d0a7a3; break; - case ATA_PIO2: timing = 0xc0d0a753; break; - case ATA_PIO3: timing = 0xc0c8a742; break; - case ATA_PIO4: timing = 0xc0c8a731; break; - case ATA_WDMA2: timing = 0xa0c8a731; break; - case ATA_UDMA2: timing = 0x90caa731; break; - case ATA_UDMA4: timing = 0x90c9a731; break; - default: timing = 0x0120a7a7; - } - break; - case 0xd9: /* 40Mhz */ - switch (mode) { - case ATA_PIO0: timing = 0xc018d9d9; break; - case ATA_PIO1: timing = 0xc010d9c7; break; - case ATA_PIO2: timing = 0xc010d997; break; - case ATA_PIO3: timing = 0xc010d974; break; - case ATA_PIO4: timing = 0xc008d963; break; - case ATA_WDMA2: timing = 0xa008d943; break; - case ATA_UDMA2: timing = 0x900bd943; break; - case ATA_UDMA4: timing = 0x900fd943; break; - default: timing = 0x0120d9d9; + case ATA_PIO0: timing = 0x06914e57; break; + case ATA_PIO1: timing = 0x06914e43; break; + case ATA_PIO2: timing = 0x06514e33; break; + case ATA_PIO3: timing = 0x06514e22; break; + case ATA_PIO4: timing = 0x06514e21; break; + case ATA_WDMA2: timing = 0x26514e21; break; + case ATA_UDMA2: timing = 0x16494e31; break; + case ATA_UDMA4: timing = 0x16454e31; break; + case ATA_UDMA5: timing = 0x16454e31; break; + default: timing = 0x06514e57; } + pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); + pci_write_config(parent, 0x5b, 0x22, 1); + } + else { /* HPT36[68] */ + switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) { + case 0x85: /* 25Mhz */ + switch (mode) { + case ATA_PIO0: timing = 0xc0d08585; break; + case ATA_PIO1: timing = 0xc0d08572; break; + case ATA_PIO2: timing = 0xc0ca8542; break; + case ATA_PIO3: timing = 0xc0ca8532; break; + case ATA_PIO4: timing = 0xc0ca8521; break; + case ATA_WDMA2: timing = 0xa0ca8521; break; + case ATA_UDMA2: timing = 0x90cf8521; break; + case ATA_UDMA4: timing = 0x90c98521; break; + default: timing = 0x01208585; + } + break; + default: + case 0xa7: /* 33MHz */ + switch (mode) { + case ATA_PIO0: timing = 0xc0d0a7aa; break; + case ATA_PIO1: timing = 0xc0d0a7a3; break; + case ATA_PIO2: timing = 0xc0d0a753; break; + case ATA_PIO3: timing = 0xc0c8a742; break; + case ATA_PIO4: timing = 0xc0c8a731; break; + case ATA_WDMA2: timing = 0xa0c8a731; break; + case ATA_UDMA2: timing = 0x90caa731; break; + case ATA_UDMA4: timing = 0x90c9a731; break; + default: timing = 0x0120a7a7; + } + break; + case 0xd9: /* 40Mhz */ + switch (mode) { + case ATA_PIO0: timing = 0xc018d9d9; break; + case ATA_PIO1: timing = 0xc010d9c7; break; + case ATA_PIO2: timing = 0xc010d997; break; + case ATA_PIO3: timing = 0xc010d974; break; + case ATA_PIO4: timing = 0xc008d963; break; + case ATA_WDMA2: timing = 0xa008d943; break; + case ATA_UDMA2: timing = 0x900bd943; break; + case ATA_UDMA4: timing = 0x900fd943; break; + default: timing = 0x0120d9d9; + } + } + pci_write_config(parent, 0x40 + (devno << 2), (timing & ~0x80000000),4); } - pci_write_config(parent, 0x40 + (devno << 2) , (timing & ~0x80000000), 4); } #else /* NPCI > 0 */