1 /* $NetBSD: viaide.c,v 1.18 2004/08/21 00:28:34 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Manuel Bouyer. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 36 #include <dev/pci/pcivar.h> 37 #include <dev/pci/pcidevs.h> 38 #include <dev/pci/pciidereg.h> 39 #include <dev/pci/pciidevar.h> 40 #include <dev/pci/pciide_apollo_reg.h> 41 42 static int via_pcib_match(struct pci_attach_args *); 43 static void via_chip_map(struct pciide_softc *, struct pci_attach_args *); 44 static void via_sata_chip_map(struct pciide_softc *, 45 struct pci_attach_args *); 46 static void via_setup_channel(struct ata_channel *); 47 48 static int viaide_match(struct device *, struct cfdata *, void *); 49 static void viaide_attach(struct device *, struct device *, void *); 50 static const struct pciide_product_desc * 51 viaide_lookup(pcireg_t); 52 53 CFATTACH_DECL(viaide, sizeof(struct pciide_softc), 54 viaide_match, viaide_attach, NULL, NULL); 55 56 static const struct pciide_product_desc pciide_amd_products[] = { 57 { PCI_PRODUCT_AMD_PBC756_IDE, 58 0, 59 "Advanced Micro Devices AMD756 IDE Controller", 60 via_chip_map 61 }, 62 { PCI_PRODUCT_AMD_PBC766_IDE, 63 0, 64 "Advanced Micro Devices AMD766 IDE Controller", 65 via_chip_map 66 }, 67 { PCI_PRODUCT_AMD_PBC768_IDE, 68 0, 69 "Advanced Micro Devices AMD768 IDE Controller", 70 via_chip_map 71 }, 72 { PCI_PRODUCT_AMD_PBC8111_IDE, 73 0, 74 "Advanced Micro Devices AMD8111 IDE Controller", 75 via_chip_map 76 }, 77 { 0, 78 0, 79 NULL, 80 NULL 81 } 82 }; 83 84 static const struct pciide_product_desc pciide_nvidia_products[] = { 85 { PCI_PRODUCT_NVIDIA_NFORCE_ATA100, 86 0, 87 "NVIDIA nForce IDE Controller", 88 via_chip_map 89 }, 90 { PCI_PRODUCT_NVIDIA_NFORCE2_ATA133, 91 0, 92 "NVIDIA nForce2 IDE Controller", 93 via_chip_map 94 }, 95 { PCI_PRODUCT_NVIDIA_NFORCE3_ATA133, 96 0, 97 "NVIDIA nForce3 IDE Controller", 98 via_chip_map 99 }, 100 { 0, 101 0, 102 NULL, 103 NULL 104 } 105 }; 106 107 static const struct pciide_product_desc pciide_via_products[] = { 108 { PCI_PRODUCT_VIATECH_VT82C586_IDE, 109 0, 110 NULL, 111 via_chip_map, 112 }, 113 { PCI_PRODUCT_VIATECH_VT82C586A_IDE, 114 0, 115 NULL, 116 via_chip_map, 117 }, 118 { PCI_PRODUCT_VIATECH_VT8237_SATA, 119 0, 120 "VIA Technologies VT8237 SATA Controller", 121 via_sata_chip_map, 122 }, 123 { 0, 124 0, 125 NULL, 126 NULL 127 } 128 }; 129 130 static const struct pciide_product_desc * 131 viaide_lookup(pcireg_t id) 132 { 133 134 switch (PCI_VENDOR(id)) { 135 case PCI_VENDOR_VIATECH: 136 return (pciide_lookup_product(id, pciide_via_products)); 137 138 case PCI_VENDOR_AMD: 139 return (pciide_lookup_product(id, pciide_amd_products)); 140 141 case PCI_VENDOR_NVIDIA: 142 return (pciide_lookup_product(id, pciide_nvidia_products)); 143 } 144 return (NULL); 145 } 146 147 static int 148 viaide_match(struct device *parent, struct cfdata *match, void *aux) 149 { 150 struct pci_attach_args *pa = aux; 151 152 if (viaide_lookup(pa->pa_id) != NULL) 153 return (2); 154 return (0); 155 } 156 157 static void 158 viaide_attach(struct device *parent, struct device *self, void *aux) 159 { 160 struct pci_attach_args *pa = aux; 161 struct pciide_softc *sc = (struct pciide_softc *)self; 162 const struct pciide_product_desc *pp; 163 164 pp = viaide_lookup(pa->pa_id); 165 if (pp == NULL) 166 panic("viaide_attach"); 167 pciide_common_attach(sc, pa, pp); 168 } 169 170 static int 171 via_pcib_match(struct pci_attach_args *pa) 172 { 173 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 174 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_ISA && 175 PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VIATECH) 176 return (1); 177 return 0; 178 } 179 180 static void 181 via_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) 182 { 183 struct pciide_channel *cp; 184 pcireg_t interface = PCI_INTERFACE(pa->pa_class); 185 pcireg_t vendor = PCI_VENDOR(pa->pa_id); 186 int channel; 187 u_int32_t ideconf; 188 bus_size_t cmdsize, ctlsize; 189 pcireg_t pcib_id, pcib_class; 190 struct pci_attach_args pcib_pa; 191 192 if (pciide_chipen(sc, pa) == 0) 193 return; 194 195 switch (vendor) { 196 case PCI_VENDOR_VIATECH: 197 /* 198 * get a PCI tag for the ISA bridge. 199 */ 200 if (pci_find_device(&pcib_pa, via_pcib_match) == 0) 201 goto unknown; 202 pcib_id = pcib_pa.pa_id; 203 pcib_class = pcib_pa.pa_class; 204 aprint_normal("%s: VIA Technologies ", 205 sc->sc_wdcdev.sc_atac.atac_dev.dv_xname); 206 switch (PCI_PRODUCT(pcib_id)) { 207 case PCI_PRODUCT_VIATECH_VT82C586_ISA: 208 aprint_normal("VT82C586 (Apollo VP) "); 209 if(PCI_REVISION(pcib_class) >= 0x02) { 210 aprint_normal("ATA33 controller\n"); 211 sc->sc_wdcdev.sc_atac.atac_udma_cap = 2; 212 } else { 213 aprint_normal("controller\n"); 214 sc->sc_wdcdev.sc_atac.atac_udma_cap = 0; 215 } 216 break; 217 case PCI_PRODUCT_VIATECH_VT82C596A: 218 aprint_normal("VT82C596A (Apollo Pro) "); 219 if (PCI_REVISION(pcib_class) >= 0x12) { 220 aprint_normal("ATA66 controller\n"); 221 sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; 222 } else { 223 aprint_normal("ATA33 controller\n"); 224 sc->sc_wdcdev.sc_atac.atac_udma_cap = 2; 225 } 226 break; 227 case PCI_PRODUCT_VIATECH_VT82C686A_ISA: 228 aprint_normal("VT82C686A (Apollo KX133) "); 229 if (PCI_REVISION(pcib_class) >= 0x40) { 230 aprint_normal("ATA100 controller\n"); 231 sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; 232 } else { 233 aprint_normal("ATA66 controller\n"); 234 sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; 235 } 236 break; 237 case PCI_PRODUCT_VIATECH_VT8231: 238 aprint_normal("VT8231 ATA100 controller\n"); 239 sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; 240 break; 241 case PCI_PRODUCT_VIATECH_VT8233: 242 aprint_normal("VT8233 ATA100 controller\n"); 243 sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; 244 break; 245 case PCI_PRODUCT_VIATECH_VT8233A: 246 aprint_normal("VT8233A ATA133 controller\n"); 247 sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; 248 break; 249 case PCI_PRODUCT_VIATECH_VT8235: 250 aprint_normal("VT8235 ATA133 controller\n"); 251 sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; 252 break; 253 case PCI_PRODUCT_VIATECH_VT8237: 254 aprint_normal("VT8237 ATA133 controller\n"); 255 sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; 256 break; 257 default: 258 unknown: 259 aprint_normal("unknown VIA ATA controller\n"); 260 sc->sc_wdcdev.sc_atac.atac_udma_cap = 0; 261 } 262 sc->sc_apo_regbase = APO_VIA_REGBASE; 263 break; 264 case PCI_VENDOR_AMD: 265 switch (sc->sc_pp->ide_product) { 266 case PCI_PRODUCT_AMD_PBC8111_IDE: 267 sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; 268 break; 269 case PCI_PRODUCT_AMD_PBC766_IDE: 270 case PCI_PRODUCT_AMD_PBC768_IDE: 271 sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; 272 break; 273 default: 274 sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; 275 } 276 sc->sc_apo_regbase = APO_AMD_REGBASE; 277 break; 278 case PCI_VENDOR_NVIDIA: 279 switch (sc->sc_pp->ide_product) { 280 case PCI_PRODUCT_NVIDIA_NFORCE_ATA100: 281 sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; 282 break; 283 case PCI_PRODUCT_NVIDIA_NFORCE2_ATA133: 284 case PCI_PRODUCT_NVIDIA_NFORCE3_ATA133: 285 sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; 286 break; 287 } 288 sc->sc_apo_regbase = APO_NVIDIA_REGBASE; 289 break; 290 default: 291 panic("via_chip_map: unknown vendor"); 292 } 293 294 aprint_normal("%s: bus-master DMA support present", 295 sc->sc_wdcdev.sc_atac.atac_dev.dv_xname); 296 pciide_mapreg_dma(sc, pa); 297 aprint_normal("\n"); 298 sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DATA32; 299 if (sc->sc_dma_ok) { 300 sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA; 301 sc->sc_wdcdev.irqack = pciide_irqack; 302 if (sc->sc_wdcdev.sc_atac.atac_udma_cap > 0) 303 sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_UDMA; 304 } 305 sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; 306 sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; 307 sc->sc_wdcdev.sc_atac.atac_set_modes = via_setup_channel; 308 sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; 309 sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; 310 311 wdc_allocate_regs(&sc->sc_wdcdev); 312 313 ATADEBUG_PRINT(("via_chip_map: old APO_IDECONF=0x%x, " 314 "APO_CTLMISC=0x%x, APO_DATATIM=0x%x, APO_UDMA=0x%x\n", 315 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)), 316 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc)), 317 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)), 318 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), 319 DEBUG_PROBE); 320 321 ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)); 322 for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; 323 channel++) { 324 cp = &sc->pciide_channels[channel]; 325 if (pciide_chansetup(sc, channel, interface) == 0) 326 continue; 327 328 if ((ideconf & APO_IDECONF_EN(channel)) == 0) { 329 aprint_normal("%s: %s channel ignored (disabled)\n", 330 sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, cp->name); 331 cp->ata_channel.ch_flags |= ATACH_DISABLED; 332 continue; 333 } 334 pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, 335 pciide_pci_intr); 336 } 337 } 338 339 static void 340 via_setup_channel(struct ata_channel *chp) 341 { 342 u_int32_t udmatim_reg, datatim_reg; 343 u_int8_t idedma_ctl; 344 int mode, drive, s; 345 struct ata_drive_datas *drvp; 346 struct atac_softc *atac = chp->ch_atac; 347 struct pciide_channel *cp = CHAN_TO_PCHAN(chp); 348 struct pciide_softc *sc = CHAN_TO_PCIIDE(chp); 349 #ifndef PCIIDE_AMD756_ENABLEDMA 350 int rev = PCI_REVISION( 351 pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG)); 352 #endif 353 354 idedma_ctl = 0; 355 datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)); 356 udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc)); 357 datatim_reg &= ~APO_DATATIM_MASK(chp->ch_channel); 358 udmatim_reg &= ~APO_UDMA_MASK(chp->ch_channel); 359 360 /* setup DMA if needed */ 361 pciide_channel_dma_setup(cp); 362 363 for (drive = 0; drive < 2; drive++) { 364 drvp = &chp->ch_drive[drive]; 365 /* If no drive, skip */ 366 if ((drvp->drive_flags & DRIVE) == 0) 367 continue; 368 /* add timing values, setup DMA if needed */ 369 if (((drvp->drive_flags & DRIVE_DMA) == 0 && 370 (drvp->drive_flags & DRIVE_UDMA) == 0)) { 371 mode = drvp->PIO_mode; 372 goto pio; 373 } 374 if ((atac->atac_cap & ATAC_CAP_UDMA) && 375 (drvp->drive_flags & DRIVE_UDMA)) { 376 /* use Ultra/DMA */ 377 s = splbio(); 378 drvp->drive_flags &= ~DRIVE_DMA; 379 splx(s); 380 udmatim_reg |= APO_UDMA_EN(chp->ch_channel, drive) | 381 APO_UDMA_EN_MTH(chp->ch_channel, drive); 382 switch (PCI_VENDOR(sc->sc_pci_id)) { 383 case PCI_VENDOR_VIATECH: 384 if (sc->sc_wdcdev.sc_atac.atac_udma_cap == 6) { 385 /* 8233a */ 386 udmatim_reg |= APO_UDMA_TIME( 387 chp->ch_channel, 388 drive, 389 via_udma133_tim[drvp->UDMA_mode]); 390 } else if (sc->sc_wdcdev.sc_atac.atac_udma_cap == 5) { 391 /* 686b */ 392 udmatim_reg |= APO_UDMA_TIME( 393 chp->ch_channel, 394 drive, 395 via_udma100_tim[drvp->UDMA_mode]); 396 } else if (sc->sc_wdcdev.sc_atac.atac_udma_cap == 4) { 397 /* 596b or 686a */ 398 udmatim_reg |= APO_UDMA_CLK66( 399 chp->ch_channel); 400 udmatim_reg |= APO_UDMA_TIME( 401 chp->ch_channel, 402 drive, 403 via_udma66_tim[drvp->UDMA_mode]); 404 } else { 405 /* 596a or 586b */ 406 udmatim_reg |= APO_UDMA_TIME( 407 chp->ch_channel, 408 drive, 409 via_udma33_tim[drvp->UDMA_mode]); 410 } 411 break; 412 case PCI_VENDOR_AMD: 413 case PCI_VENDOR_NVIDIA: 414 udmatim_reg |= APO_UDMA_TIME(chp->ch_channel, 415 drive, amd7x6_udma_tim[drvp->UDMA_mode]); 416 break; 417 } 418 /* can use PIO timings, MW DMA unused */ 419 mode = drvp->PIO_mode; 420 } else { 421 /* use Multiword DMA, but only if revision is OK */ 422 s = splbio(); 423 drvp->drive_flags &= ~DRIVE_UDMA; 424 splx(s); 425 #ifndef PCIIDE_AMD756_ENABLEDMA 426 /* 427 * The workaround doesn't seem to be necessary 428 * with all drives, so it can be disabled by 429 * PCIIDE_AMD756_ENABLEDMA. It causes a hard hang if 430 * triggered. 431 */ 432 if (PCI_VENDOR(sc->sc_pci_id) == PCI_VENDOR_AMD && 433 sc->sc_pp->ide_product == 434 PCI_PRODUCT_AMD_PBC756_IDE && 435 AMD756_CHIPREV_DISABLEDMA(rev)) { 436 aprint_normal( 437 "%s:%d:%d: multi-word DMA disabled due " 438 "to chip revision\n", 439 sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, 440 chp->ch_channel, drive); 441 mode = drvp->PIO_mode; 442 s = splbio(); 443 drvp->drive_flags &= ~DRIVE_DMA; 444 splx(s); 445 goto pio; 446 } 447 #endif 448 /* mode = min(pio, dma+2) */ 449 if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) 450 mode = drvp->PIO_mode; 451 else 452 mode = drvp->DMA_mode + 2; 453 } 454 idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); 455 456 pio: /* setup PIO mode */ 457 if (mode <= 2) { 458 drvp->DMA_mode = 0; 459 drvp->PIO_mode = 0; 460 mode = 0; 461 } else { 462 drvp->PIO_mode = mode; 463 drvp->DMA_mode = mode - 2; 464 } 465 datatim_reg |= 466 APO_DATATIM_PULSE(chp->ch_channel, drive, 467 apollo_pio_set[mode]) | 468 APO_DATATIM_RECOV(chp->ch_channel, drive, 469 apollo_pio_rec[mode]); 470 } 471 if (idedma_ctl != 0) { 472 /* Add software bits in status register */ 473 bus_space_write_1(sc->sc_dma_iot, cp->dma_iohs[IDEDMA_CTL], 0, 474 idedma_ctl); 475 } 476 pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc), datatim_reg); 477 pci_conf_write(sc->sc_pc, sc->sc_tag, APO_UDMA(sc), udmatim_reg); 478 ATADEBUG_PRINT(("via_chip_map: APO_DATATIM=0x%x, APO_UDMA=0x%x\n", 479 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)), 480 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), DEBUG_PROBE); 481 } 482 483 static void 484 via_sata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) 485 { 486 struct pciide_channel *cp; 487 pcireg_t interface = PCI_INTERFACE(pa->pa_class); 488 int channel; 489 bus_size_t cmdsize, ctlsize; 490 491 if (pciide_chipen(sc, pa) == 0) 492 return; 493 494 if (interface == 0) { 495 ATADEBUG_PRINT(("via_sata_chip_map interface == 0\n"), 496 DEBUG_PROBE); 497 interface = PCIIDE_INTERFACE_BUS_MASTER_DMA | 498 PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1); 499 } 500 501 aprint_normal("%s: bus-master DMA support present", 502 sc->sc_wdcdev.sc_atac.atac_dev.dv_xname); 503 pciide_mapreg_dma(sc, pa); 504 aprint_normal("\n"); 505 506 if (sc->sc_dma_ok) { 507 sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_UDMA | ATAC_CAP_DMA; 508 sc->sc_wdcdev.irqack = pciide_irqack; 509 } 510 sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; 511 sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; 512 sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; 513 514 sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; 515 sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; 516 sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32; 517 sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel; 518 519 wdc_allocate_regs(&sc->sc_wdcdev); 520 521 for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; 522 channel++) { 523 cp = &sc->pciide_channels[channel]; 524 if (pciide_chansetup(sc, channel, interface) == 0) 525 continue; 526 pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, 527 pciide_pci_intr); 528 } 529 } 530