From 88bdf804eddbec85de6bd3e143c1c325034bb1c7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=B8ren=20Schmidt?= Date: Wed, 8 Dec 2004 11:17:38 +0000 Subject: [PATCH] Add support for the ITE IT8212F controller. HW donated by: Yahoo! --- sys/dev/ata/ata-chipset.c | 96 +++++++++++++++++++++++++++++++++++++++ sys/dev/ata/ata-pci.c | 15 ++++-- sys/dev/ata/ata-pci.h | 11 +++++ 3 files changed, 117 insertions(+), 5 deletions(-) diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c index 6cc76b7cd09..4d8446bd357 100644 --- a/sys/dev/ata/ata-chipset.c +++ b/sys/dev/ata/ata-chipset.c @@ -83,6 +83,8 @@ static void ata_intel_intr(void *); static void ata_intel_reset(struct ata_channel *); static void ata_intel_old_setmode(struct ata_device *, int); static void ata_intel_new_setmode(struct ata_device *, int); +static int ata_ite_chipinit(device_t); +static void ata_ite_setmode(struct ata_device *, int); static int ata_national_chipinit(device_t); static void ata_national_setmode(struct ata_device *, int); static int ata_nvidia_chipinit(device_t); @@ -1014,6 +1016,100 @@ ata_intel_new_setmode(struct ata_device *atadev, int mode) atadev->mode = mode; } +/* + * Integrated Technology Express Inc. (ITE) chipset support functions + */ +int +ata_ite_ident(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + + if (pci_get_devid(dev) == ATA_IT8212F) { + device_set_desc(dev, "ITE IT8212F ATA133 controller"); + ctlr->chipinit = ata_ite_chipinit; + return 0; + } + return ENXIO; +} + +static int +ata_ite_chipinit(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + + if (ata_setup_interrupt(dev)) + return ENXIO; + + ctlr->setmode = ata_ite_setmode; + + /* set PCI mode and 66Mhz reference clock */ + pci_write_config(dev, 0x50, pci_read_config(dev, 0x50, 1) & ~0x83, 1); + + /* set default active & recover timings */ + pci_write_config(dev, 0x54, 0x31, 1); + pci_write_config(dev, 0x56, 0x31, 1); + return 0; +} + +static void +ata_ite_setmode(struct ata_device *atadev, int mode) +{ + device_t parent = device_get_parent(atadev->channel->dev); + struct ata_channel *ch = atadev->channel; + int devno = (ch->unit << 1) + ATA_DEV(atadev->unit); + int error; + + /* correct the mode for what the HW supports */ + mode = ata_limit_mode(atadev, mode, ATA_UDMA6); + + /* check the CBLID bits for 80 conductor cable detection */ + if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x40, 2) & + (ch->unit ? (1<<3) : (1<<2)))) { + ata_prtdev(atadev,"DMA limited to UDMA33, non-ATA66 cable or device\n"); + mode = ATA_UDMA2; + } + + /* set the wanted mode on the device */ + error = ata_controlcmd(atadev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); + + if (bootverbose) + ata_prtdev(atadev, "%s setting %s on ITE8212F chip\n", + (error) ? "failed" : "success", ata_mode2str(mode)); + + /* if the device accepted the mode change, setup the HW accordingly */ + if (!error) { + if (mode >= ATA_UDMA0) { + u_int8_t udmatiming[] = + { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 }; + + /* enable UDMA mode */ + pci_write_config(parent, 0x50, + pci_read_config(parent, 0x50, 1) & + ~(1 << (devno + 3)), 1); + + /* set UDMA timing */ + pci_write_config(parent, + 0x56 + (ch->unit << 2) + ATA_DEV(atadev->unit), + udmatiming[mode & ATA_MODE_MASK], 1); + } + else { + u_int8_t chtiming[] = + { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 }; + + /* disable UDMA mode */ + pci_write_config(parent, 0x50, + pci_read_config(parent, 0x50, 1) | + (1 << (devno + 3)), 1); + + /* set active and recover timing (shared between master & slave) */ + if (pci_read_config(parent, 0x54 + (ch->unit << 2), 1) < + chtiming[ata_mode2idx(mode)]) + pci_write_config(parent, 0x54 + (ch->unit << 2), + chtiming[ata_mode2idx(mode)], 1); + } + atadev->mode = mode; + } +} /* * National chipset support functions */ diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index b5d7388188d..747ba419ca3 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -106,6 +106,10 @@ ata_pci_probe(device_t dev) if (!ata_intel_ident(dev)) return 0; break; + case ATA_ITE_ID: + if (!ata_ite_ident(dev)) + return 0; + break; case ATA_NATIONAL_ID: if (!ata_national_ident(dev)) return 0; @@ -134,18 +138,19 @@ ata_pci_probe(device_t dev) if (!ata_via_ident(dev)) return 0; break; - case 0x16ca: - if (pci_get_devid(dev) == 0x000116ca) { + case ATA_CENATEK_ID: + if (pci_get_devid(dev) == ATA_CENATEK_ROCKET) { ata_generic_ident(dev); device_set_desc(dev, "Cenatek Rocket Drive controller"); return 0; } break; - case 0x1042: - if (pci_get_devid(dev)==0x10001042 || pci_get_devid(dev)==0x10011042) { + case ATA_MICRON_ID: + if (pci_get_devid(dev) == ATA_MICRON_RZ1000 || + pci_get_devid(dev) == ATA_MICRON_RZ1001) { ata_generic_ident(dev); device_set_desc(dev, - "RZ 100? ATA controller !WARNING! buggy HW data loss possible"); + "RZ 100? ATA controller !WARNING! data loss/corruption risk"); return 0; } break; diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index e054bcbd07a..5189e700a9b 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -83,6 +83,9 @@ struct ata_pci_controller { #define ATA_ACER_LABS_ID 0x10b9 #define ATA_ALI_5229 0x522910b9 +#define ATA_CENATEK_ID 0x16ca +#define ATA_CENATEK_ROCKET 0x000116ca + #define ATA_CYRIX_ID 0x1078 #define ATA_CYRIX_5530 0x01021078 @@ -125,6 +128,13 @@ struct ata_pci_controller { #define ATA_I82801FB_S1 0x26518086 #define ATA_I82801FB_R1 0x26528086 +#define ATA_ITE_ID 0x1283 +#define ATA_IT8212F 0x82121283 + +#define ATA_MICRON_ID 0x1042 +#define ATA_MICRON_RZ1000 0x10001042 +#define ATA_MICRON_RZ1001 0x10011042 + #define ATA_NATIONAL_ID 0x100b #define ATA_SC1100 0x0502100b @@ -328,6 +338,7 @@ int ata_cyrix_ident(device_t); int ata_cypress_ident(device_t); int ata_highpoint_ident(device_t); int ata_intel_ident(device_t); +int ata_ite_ident(device_t); int ata_national_ident(device_t); int ata_nvidia_ident(device_t); int ata_promise_ident(device_t); -- 2.45.2