static bool viaide_suspend(device_t dv, const pmf_qual_t *qual) { struct pciide_softc *sc = device_private(dv); sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)); /* APO_DATATIM(sc) includes APO_UDMA(sc) */ sc->sc_pm_reg[1] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)); /* This two are VIA-only, but should be ignored by other devices. */ sc->sc_pm_reg[2] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc)); sc->sc_pm_reg[3] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_MISCTIM(sc)); return true; }
static bool viaide_resume(device_t dv, const pmf_qual_t *qual) { struct pciide_softc *sc = device_private(dv); pci_conf_write(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc), sc->sc_pm_reg[0]); pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc), sc->sc_pm_reg[1]); /* This two are VIA-only, but should be ignored by other devices. */ pci_conf_write(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc), sc->sc_pm_reg[2]); pci_conf_write(sc->sc_pc, sc->sc_tag, APO_MISCTIM(sc), sc->sc_pm_reg[3]); return true; }
static void via_setup_channel(struct ata_channel *chp) { u_int32_t udmatim_reg, datatim_reg; u_int8_t idedma_ctl; int mode, drive, s; struct ata_drive_datas *drvp; struct atac_softc *atac = chp->ch_atac; struct pciide_channel *cp = CHAN_TO_PCHAN(chp); struct pciide_softc *sc = CHAN_TO_PCIIDE(chp); #ifndef PCIIDE_AMD756_ENABLEDMA int rev = PCI_REVISION( pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG)); #endif idedma_ctl = 0; datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)); udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc)); datatim_reg &= ~APO_DATATIM_MASK(chp->ch_channel); udmatim_reg &= ~APO_UDMA_MASK(chp->ch_channel); /* setup DMA if needed */ pciide_channel_dma_setup(cp); for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ if (((drvp->drive_flags & ATA_DRIVE_DMA) == 0 && (drvp->drive_flags & ATA_DRIVE_UDMA) == 0)) { mode = drvp->PIO_mode; goto pio; } if ((atac->atac_cap & ATAC_CAP_UDMA) && (drvp->drive_flags & ATA_DRIVE_UDMA)) { /* use Ultra/DMA */ s = splbio(); drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); udmatim_reg |= APO_UDMA_EN(chp->ch_channel, drive) | APO_UDMA_EN_MTH(chp->ch_channel, drive); switch (PCI_VENDOR(sc->sc_pci_id)) { case PCI_VENDOR_VIATECH: if (sc->sc_wdcdev.sc_atac.atac_udma_cap == 6) { /* 8233a */ udmatim_reg |= APO_UDMA_TIME( chp->ch_channel, drive, via_udma133_tim[drvp->UDMA_mode]); } else if (sc->sc_wdcdev.sc_atac.atac_udma_cap == 5) { /* 686b */ udmatim_reg |= APO_UDMA_TIME( chp->ch_channel, drive, via_udma100_tim[drvp->UDMA_mode]); } else if (sc->sc_wdcdev.sc_atac.atac_udma_cap == 4) { /* 596b or 686a */ udmatim_reg |= APO_UDMA_CLK66( chp->ch_channel); udmatim_reg |= APO_UDMA_TIME( chp->ch_channel, drive, via_udma66_tim[drvp->UDMA_mode]); } else { /* 596a or 586b */ udmatim_reg |= APO_UDMA_TIME( chp->ch_channel, drive, via_udma33_tim[drvp->UDMA_mode]); } break; case PCI_VENDOR_AMD: case PCI_VENDOR_NVIDIA: udmatim_reg |= APO_UDMA_TIME(chp->ch_channel, drive, amd7x6_udma_tim[drvp->UDMA_mode]); break; } /* can use PIO timings, MW DMA unused */ mode = drvp->PIO_mode; } else { /* use Multiword DMA, but only if revision is OK */ s = splbio(); drvp->drive_flags &= ~ATA_DRIVE_UDMA; splx(s); #ifndef PCIIDE_AMD756_ENABLEDMA /* * The workaround doesn't seem to be necessary * with all drives, so it can be disabled by * PCIIDE_AMD756_ENABLEDMA. It causes a hard hang if * triggered. */ if (PCI_VENDOR(sc->sc_pci_id) == PCI_VENDOR_AMD && sc->sc_pp->ide_product == PCI_PRODUCT_AMD_PBC756_IDE && AMD756_CHIPREV_DISABLEDMA(rev)) { aprint_normal( "%s:%d:%d: multi-word DMA disabled due " "to chip revision\n", device_xname( sc->sc_wdcdev.sc_atac.atac_dev), chp->ch_channel, drive); mode = drvp->PIO_mode; s = splbio(); drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); goto pio; } #endif /* mode = min(pio, dma+2) */ if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) mode = drvp->PIO_mode; else mode = drvp->DMA_mode + 2; } idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); pio: /* setup PIO mode */ if (mode <= 2) { drvp->DMA_mode = 0; drvp->PIO_mode = 0; mode = 0; } else { drvp->PIO_mode = mode; drvp->DMA_mode = mode - 2; } datatim_reg |= APO_DATATIM_PULSE(chp->ch_channel, drive, apollo_pio_set[mode]) | APO_DATATIM_RECOV(chp->ch_channel, drive, apollo_pio_rec[mode]); } if (idedma_ctl != 0) { /* Add software bits in status register */ bus_space_write_1(sc->sc_dma_iot, cp->dma_iohs[IDEDMA_CTL], 0, idedma_ctl); } pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc), datatim_reg); pci_conf_write(sc->sc_pc, sc->sc_tag, APO_UDMA(sc), udmatim_reg); ATADEBUG_PRINT(("via_chip_map: APO_DATATIM=0x%x, APO_UDMA=0x%x\n", pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)), pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), DEBUG_PROBE); }
static void via_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) { struct pciide_channel *cp; pcireg_t interface = PCI_INTERFACE(pa->pa_class); pcireg_t vendor = PCI_VENDOR(pa->pa_id); int channel; u_int32_t ideconf; pcireg_t pcib_id, pcib_class; struct pci_attach_args pcib_pa; if (pciide_chipen(sc, pa) == 0) return; switch (vendor) { case PCI_VENDOR_VIATECH: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_VIATECH_VT6410_RAID: aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, "VIA Technologies VT6410 IDE controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; interface = PCIIDE_INTERFACE_BUS_MASTER_DMA | PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1); break; case PCI_PRODUCT_VIATECH_VX900_IDE: aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, "VIA Technologies VX900 ATA133 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; break; default: /* * get a PCI tag for the ISA bridge. */ if (pci_find_device(&pcib_pa, via_pcib_match) == 0) goto unknown; pcib_id = pcib_pa.pa_id; pcib_class = pcib_pa.pa_class; aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, "VIA Technologies "); switch (PCI_PRODUCT(pcib_id)) { case PCI_PRODUCT_VIATECH_VT82C586_ISA: aprint_normal("VT82C586 (Apollo VP) "); if(PCI_REVISION(pcib_class) >= 0x02) { aprint_normal("ATA33 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 2; } else { aprint_normal("controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 0; } break; case PCI_PRODUCT_VIATECH_VT82C596A: aprint_normal("VT82C596A (Apollo Pro) "); if (PCI_REVISION(pcib_class) >= 0x12) { aprint_normal("ATA66 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; } else { aprint_normal("ATA33 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 2; } break; case PCI_PRODUCT_VIATECH_VT82C686A_ISA: aprint_normal("VT82C686A (Apollo KX133) "); if (PCI_REVISION(pcib_class) >= 0x40) { aprint_normal("ATA100 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; } else { aprint_normal("ATA66 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; } break; case PCI_PRODUCT_VIATECH_VT8231: aprint_normal("VT8231 ATA100 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; break; case PCI_PRODUCT_VIATECH_VT8233: aprint_normal("VT8233 ATA100 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; break; case PCI_PRODUCT_VIATECH_VT8233A: aprint_normal("VT8233A ATA133 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; break; case PCI_PRODUCT_VIATECH_VT8235: aprint_normal("VT8235 ATA133 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; break; case PCI_PRODUCT_VIATECH_VT8237: aprint_normal("VT8237 ATA133 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; break; case PCI_PRODUCT_VIATECH_VT8237A_ISA: aprint_normal("VT8237A ATA133 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; break; case PCI_PRODUCT_VIATECH_CX700: aprint_normal("CX700 ATA133 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; break; case PCI_PRODUCT_VIATECH_VT8251: aprint_normal("VT8251 ATA133 controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; break; default: unknown: aprint_normal("unknown VIA ATA controller\n"); sc->sc_wdcdev.sc_atac.atac_udma_cap = 0; } break; } sc->sc_apo_regbase = APO_VIA_REGBASE; break; case PCI_VENDOR_AMD: switch (sc->sc_pp->ide_product) { case PCI_PRODUCT_AMD_PBC8111_IDE: sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; break; case PCI_PRODUCT_AMD_CS5536_IDE: case PCI_PRODUCT_AMD_PBC766_IDE: case PCI_PRODUCT_AMD_PBC768_IDE: sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; break; default: sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; } sc->sc_apo_regbase = APO_AMD_REGBASE; break; case PCI_VENDOR_NVIDIA: switch (sc->sc_pp->ide_product) { case PCI_PRODUCT_NVIDIA_NFORCE_ATA100: sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; break; case PCI_PRODUCT_NVIDIA_NFORCE2_ATA133: case PCI_PRODUCT_NVIDIA_NFORCE2_400_ATA133: case PCI_PRODUCT_NVIDIA_NFORCE3_ATA133: case PCI_PRODUCT_NVIDIA_NFORCE3_250_ATA133: case PCI_PRODUCT_NVIDIA_NFORCE4_ATA133: case PCI_PRODUCT_NVIDIA_NFORCE430_ATA133: case PCI_PRODUCT_NVIDIA_MCP04_IDE: case PCI_PRODUCT_NVIDIA_MCP55_IDE: case PCI_PRODUCT_NVIDIA_MCP61_IDE: case PCI_PRODUCT_NVIDIA_MCP65_IDE: case PCI_PRODUCT_NVIDIA_MCP67_IDE: case PCI_PRODUCT_NVIDIA_MCP73_IDE: case PCI_PRODUCT_NVIDIA_MCP77_IDE: sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; break; } sc->sc_apo_regbase = APO_NVIDIA_REGBASE; break; default: panic("via_chip_map: unknown vendor"); } aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, "bus-master DMA support present"); pciide_mapreg_dma(sc, pa); aprint_verbose("\n"); sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DATA32; if (sc->sc_dma_ok) { sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA; sc->sc_wdcdev.irqack = pciide_irqack; if (sc->sc_wdcdev.sc_atac.atac_udma_cap > 0) sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_UDMA; } sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; sc->sc_wdcdev.sc_atac.atac_set_modes = via_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; sc->sc_wdcdev.wdc_maxdrives = 2; if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_RAID; wdc_allocate_regs(&sc->sc_wdcdev); ATADEBUG_PRINT(("via_chip_map: old APO_IDECONF=0x%x, " "APO_CTLMISC=0x%x, APO_DATATIM=0x%x, APO_UDMA=0x%x\n", pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)), pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc)), pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)), pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), DEBUG_PROBE); ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)); for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; channel++) { cp = &sc->pciide_channels[channel]; if (pciide_chansetup(sc, channel, interface) == 0) continue; if ((ideconf & APO_IDECONF_EN(channel)) == 0) { aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, "%s channel ignored (disabled)\n", cp->name); cp->ata_channel.ch_flags |= ATACH_DISABLED; continue; } via_mapchan(pa, cp, interface, pciide_pci_intr); } }
static void via_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) { struct pciide_channel *cp; pcireg_t interface = PCI_INTERFACE(pa->pa_class); pcireg_t vendor = PCI_VENDOR(pa->pa_id); int channel; u_int32_t ideconf; bus_size_t cmdsize, ctlsize; pcireg_t pcib_id, pcib_class; struct pci_attach_args pcib_pa; if (pciide_chipen(sc, pa) == 0) return; switch (vendor) { case PCI_VENDOR_VIATECH: /* * get a PCI tag for the ISA bridge. */ if (pci_enumerate_bus( (struct pci_softc *)sc->sc_wdcdev.sc_dev.dv_parent, via_pcib_match, &pcib_pa) == 0) goto unknown; pcib_id = pcib_pa.pa_id; pcib_class = pcib_pa.pa_class; aprint_normal("%s: VIA Technologies ", sc->sc_wdcdev.sc_dev.dv_xname); switch (PCI_PRODUCT(pcib_id)) { case PCI_PRODUCT_VIATECH_VT82C586_ISA: aprint_normal("VT82C586 (Apollo VP) "); if(PCI_REVISION(pcib_class) >= 0x02) { aprint_normal("ATA33 controller\n"); sc->sc_wdcdev.UDMA_cap = 2; } else { aprint_normal("controller\n"); sc->sc_wdcdev.UDMA_cap = 0; } break; case PCI_PRODUCT_VIATECH_VT82C596A: aprint_normal("VT82C596A (Apollo Pro) "); if (PCI_REVISION(pcib_class) >= 0x12) { aprint_normal("ATA66 controller\n"); sc->sc_wdcdev.UDMA_cap = 4; } else { aprint_normal("ATA33 controller\n"); sc->sc_wdcdev.UDMA_cap = 2; } break; case PCI_PRODUCT_VIATECH_VT82C686A_ISA: aprint_normal("VT82C686A (Apollo KX133) "); if (PCI_REVISION(pcib_class) >= 0x40) { aprint_normal("ATA100 controller\n"); sc->sc_wdcdev.UDMA_cap = 5; } else { aprint_normal("ATA66 controller\n"); sc->sc_wdcdev.UDMA_cap = 4; } break; case PCI_PRODUCT_VIATECH_VT8231: aprint_normal("VT8231 ATA100 controller\n"); sc->sc_wdcdev.UDMA_cap = 5; break; case PCI_PRODUCT_VIATECH_VT8233: aprint_normal("VT8233 ATA100 controller\n"); sc->sc_wdcdev.UDMA_cap = 5; break; case PCI_PRODUCT_VIATECH_VT8233A: aprint_normal("VT8233A ATA133 controller\n"); sc->sc_wdcdev.UDMA_cap = 6; break; case PCI_PRODUCT_VIATECH_VT8235: aprint_normal("VT8235 ATA133 controller\n"); sc->sc_wdcdev.UDMA_cap = 6; break; case PCI_PRODUCT_VIATECH_VT8237: aprint_normal("VT8237 ATA133 controller\n"); sc->sc_wdcdev.UDMA_cap = 6; break; default: unknown: aprint_normal("unknown VIA ATA controller\n"); sc->sc_wdcdev.UDMA_cap = 0; } sc->sc_apo_regbase = APO_VIA_REGBASE; break; case PCI_VENDOR_AMD: switch (sc->sc_pp->ide_product) { case PCI_PRODUCT_AMD_PBC8111_IDE: sc->sc_wdcdev.UDMA_cap = 6; break; case PCI_PRODUCT_AMD_PBC766_IDE: case PCI_PRODUCT_AMD_PBC768_IDE: sc->sc_wdcdev.UDMA_cap = 5; break; default: sc->sc_wdcdev.UDMA_cap = 4; } sc->sc_apo_regbase = APO_AMD_REGBASE; break; case PCI_VENDOR_NVIDIA: switch (sc->sc_pp->ide_product) { case PCI_PRODUCT_NVIDIA_NFORCE_ATA100: sc->sc_wdcdev.UDMA_cap = 5; break; case PCI_PRODUCT_NVIDIA_NFORCE2_ATA133: case PCI_PRODUCT_NVIDIA_NFORCE3_ATA133: sc->sc_wdcdev.UDMA_cap = 6; break; } sc->sc_apo_regbase = APO_NVIDIA_REGBASE; break; default: panic("via_chip_map: unknown vendor"); } aprint_normal("%s: bus-master DMA support present", sc->sc_wdcdev.sc_dev.dv_xname); pciide_mapreg_dma(sc, pa); aprint_normal("\n"); sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 | WDC_CAPABILITY_MODE; if (sc->sc_dma_ok) { sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK; sc->sc_wdcdev.irqack = pciide_irqack; if (sc->sc_wdcdev.UDMA_cap > 0) sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA; } sc->sc_wdcdev.PIO_cap = 4; sc->sc_wdcdev.DMA_cap = 2; sc->sc_wdcdev.set_modes = via_setup_channel; sc->sc_wdcdev.channels = sc->wdc_chanarray; sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS; WDCDEBUG_PRINT(("via_chip_map: old APO_IDECONF=0x%x, " "APO_CTLMISC=0x%x, APO_DATATIM=0x%x, APO_UDMA=0x%x\n", pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)), pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc)), pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)), pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), DEBUG_PROBE); ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)); for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { cp = &sc->pciide_channels[channel]; if (pciide_chansetup(sc, channel, interface) == 0) continue; if ((ideconf & APO_IDECONF_EN(channel)) == 0) { aprint_normal("%s: %s channel ignored (disabled)\n", sc->sc_wdcdev.sc_dev.dv_xname, cp->name); cp->wdc_channel.ch_flags |= WDCF_DISABLED; continue; } pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, pciide_pci_intr); } }