1 /* $NetBSD: viaide.c,v 1.9 2004/01/03 22:56:53 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 wdc_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 { 0, 96 0, 97 NULL, 98 NULL 99 } 100 }; 101 102 static const struct pciide_product_desc pciide_via_products[] = { 103 { PCI_PRODUCT_VIATECH_VT82C586_IDE, 104 0, 105 NULL, 106 via_chip_map, 107 }, 108 { PCI_PRODUCT_VIATECH_VT82C586A_IDE, 109 0, 110 NULL, 111 via_chip_map, 112 }, 113 { PCI_PRODUCT_VIATECH_VT8237_SATA, 114 0, 115 "VIA Technologies VT8237 SATA Controller", 116 via_sata_chip_map, 117 }, 118 { 0, 119 0, 120 NULL, 121 NULL 122 } 123 }; 124 125 static const struct pciide_product_desc * 126 viaide_lookup(pcireg_t id) 127 { 128 129 switch (PCI_VENDOR(id)) { 130 case PCI_VENDOR_VIATECH: 131 return (pciide_lookup_product(id, pciide_via_products)); 132 133 case PCI_VENDOR_AMD: 134 return (pciide_lookup_product(id, pciide_amd_products)); 135 136 case PCI_VENDOR_NVIDIA: 137 return (pciide_lookup_product(id, pciide_nvidia_products)); 138 } 139 return (NULL); 140 } 141 142 static int 143 viaide_match(struct device *parent, struct cfdata *match, void *aux) 144 { 145 struct pci_attach_args *pa = aux; 146 147 if (viaide_lookup(pa->pa_id) != NULL) 148 return (2); 149 return (0); 150 } 151 152 static void 153 viaide_attach(struct device *parent, struct device *self, void *aux) 154 { 155 struct pci_attach_args *pa = aux; 156 struct pciide_softc *sc = (struct pciide_softc *)self; 157 const struct pciide_product_desc *pp; 158 159 pp = viaide_lookup(pa->pa_id); 160 if (pp == NULL) 161 panic("viaide_attach"); 162 pciide_common_attach(sc, pa, pp); 163 } 164 165 static int 166 via_pcib_match(struct pci_attach_args *pa) 167 { 168 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 169 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_ISA && 170 PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VIATECH) 171 return (1); 172 return 0; 173 } 174 175 static void 176 via_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) 177 { 178 struct pciide_channel *cp; 179 pcireg_t interface = PCI_INTERFACE(pa->pa_class); 180 pcireg_t vendor = PCI_VENDOR(pa->pa_id); 181 int channel; 182 u_int32_t ideconf; 183 bus_size_t cmdsize, ctlsize; 184 pcireg_t pcib_id, pcib_class; 185 struct pci_attach_args pcib_pa; 186 187 if (pciide_chipen(sc, pa) == 0) 188 return; 189 190 switch (vendor) { 191 case PCI_VENDOR_VIATECH: 192 /* 193 * get a PCI tag for the ISA bridge. 194 */ 195 if (pci_enumerate_bus( 196 (struct pci_softc *)sc->sc_wdcdev.sc_dev.dv_parent, 197 via_pcib_match, &pcib_pa) == 0) 198 goto unknown; 199 pcib_id = pcib_pa.pa_id; 200 pcib_class = pcib_pa.pa_class; 201 aprint_normal("%s: VIA Technologies ", 202 sc->sc_wdcdev.sc_dev.dv_xname); 203 switch (PCI_PRODUCT(pcib_id)) { 204 case PCI_PRODUCT_VIATECH_VT82C586_ISA: 205 aprint_normal("VT82C586 (Apollo VP) "); 206 if(PCI_REVISION(pcib_class) >= 0x02) { 207 aprint_normal("ATA33 controller\n"); 208 sc->sc_wdcdev.UDMA_cap = 2; 209 } else { 210 aprint_normal("controller\n"); 211 sc->sc_wdcdev.UDMA_cap = 0; 212 } 213 break; 214 case PCI_PRODUCT_VIATECH_VT82C596A: 215 aprint_normal("VT82C596A (Apollo Pro) "); 216 if (PCI_REVISION(pcib_class) >= 0x12) { 217 aprint_normal("ATA66 controller\n"); 218 sc->sc_wdcdev.UDMA_cap = 4; 219 } else { 220 aprint_normal("ATA33 controller\n"); 221 sc->sc_wdcdev.UDMA_cap = 2; 222 } 223 break; 224 case PCI_PRODUCT_VIATECH_VT82C686A_ISA: 225 aprint_normal("VT82C686A (Apollo KX133) "); 226 if (PCI_REVISION(pcib_class) >= 0x40) { 227 aprint_normal("ATA100 controller\n"); 228 sc->sc_wdcdev.UDMA_cap = 5; 229 } else { 230 aprint_normal("ATA66 controller\n"); 231 sc->sc_wdcdev.UDMA_cap = 4; 232 } 233 break; 234 case PCI_PRODUCT_VIATECH_VT8231: 235 aprint_normal("VT8231 ATA100 controller\n"); 236 sc->sc_wdcdev.UDMA_cap = 5; 237 break; 238 case PCI_PRODUCT_VIATECH_VT8233: 239 aprint_normal("VT8233 ATA100 controller\n"); 240 sc->sc_wdcdev.UDMA_cap = 5; 241 break; 242 case PCI_PRODUCT_VIATECH_VT8233A: 243 aprint_normal("VT8233A ATA133 controller\n"); 244 sc->sc_wdcdev.UDMA_cap = 6; 245 break; 246 case PCI_PRODUCT_VIATECH_VT8235: 247 aprint_normal("VT8235 ATA133 controller\n"); 248 sc->sc_wdcdev.UDMA_cap = 6; 249 break; 250 case PCI_PRODUCT_VIATECH_VT8237: 251 aprint_normal("VT8237 ATA133 controller\n"); 252 sc->sc_wdcdev.UDMA_cap = 6; 253 break; 254 default: 255 unknown: 256 aprint_normal("unknown VIA ATA controller\n"); 257 sc->sc_wdcdev.UDMA_cap = 0; 258 } 259 sc->sc_apo_regbase = APO_VIA_REGBASE; 260 break; 261 case PCI_VENDOR_AMD: 262 switch (sc->sc_pp->ide_product) { 263 case PCI_PRODUCT_AMD_PBC766_IDE: 264 case PCI_PRODUCT_AMD_PBC768_IDE: 265 case PCI_PRODUCT_AMD_PBC8111_IDE: 266 sc->sc_wdcdev.UDMA_cap = 5; 267 break; 268 default: 269 sc->sc_wdcdev.UDMA_cap = 4; 270 } 271 sc->sc_apo_regbase = APO_AMD_REGBASE; 272 break; 273 case PCI_VENDOR_NVIDIA: 274 switch (sc->sc_pp->ide_product) { 275 case PCI_PRODUCT_NVIDIA_NFORCE_ATA100: 276 sc->sc_wdcdev.UDMA_cap = 5; 277 break; 278 case PCI_PRODUCT_NVIDIA_NFORCE2_ATA133: 279 case PCI_PRODUCT_NVIDIA_NFORCE3_ATA133: 280 sc->sc_wdcdev.UDMA_cap = 6; 281 break; 282 } 283 sc->sc_apo_regbase = APO_NVIDIA_REGBASE; 284 break; 285 default: 286 panic("via_chip_map: unknown vendor"); 287 } 288 289 aprint_normal("%s: bus-master DMA support present", 290 sc->sc_wdcdev.sc_dev.dv_xname); 291 pciide_mapreg_dma(sc, pa); 292 aprint_normal("\n"); 293 sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 | 294 WDC_CAPABILITY_MODE; 295 if (sc->sc_dma_ok) { 296 sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK; 297 sc->sc_wdcdev.irqack = pciide_irqack; 298 if (sc->sc_wdcdev.UDMA_cap > 0) 299 sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA; 300 } 301 sc->sc_wdcdev.PIO_cap = 4; 302 sc->sc_wdcdev.DMA_cap = 2; 303 sc->sc_wdcdev.set_modes = via_setup_channel; 304 sc->sc_wdcdev.channels = sc->wdc_chanarray; 305 sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS; 306 307 WDCDEBUG_PRINT(("via_chip_map: old APO_IDECONF=0x%x, " 308 "APO_CTLMISC=0x%x, APO_DATATIM=0x%x, APO_UDMA=0x%x\n", 309 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)), 310 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc)), 311 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)), 312 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), 313 DEBUG_PROBE); 314 315 ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)); 316 for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { 317 cp = &sc->pciide_channels[channel]; 318 if (pciide_chansetup(sc, channel, interface) == 0) 319 continue; 320 321 if ((ideconf & APO_IDECONF_EN(channel)) == 0) { 322 aprint_normal("%s: %s channel ignored (disabled)\n", 323 sc->sc_wdcdev.sc_dev.dv_xname, cp->name); 324 cp->wdc_channel.ch_flags |= WDCF_DISABLED; 325 continue; 326 } 327 pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, 328 pciide_pci_intr); 329 } 330 } 331 332 static void 333 via_setup_channel(struct wdc_channel *chp) 334 { 335 u_int32_t udmatim_reg, datatim_reg; 336 u_int8_t idedma_ctl; 337 int mode, drive; 338 struct ata_drive_datas *drvp; 339 struct pciide_channel *cp = (struct pciide_channel*)chp; 340 struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.ch_wdc; 341 struct wdc_softc *wdc = &sc->sc_wdcdev; 342 #ifndef PCIIDE_AMD756_ENABLEDMA 343 int rev = PCI_REVISION( 344 pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG)); 345 #endif 346 347 idedma_ctl = 0; 348 datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)); 349 udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc)); 350 datatim_reg &= ~APO_DATATIM_MASK(chp->ch_channel); 351 udmatim_reg &= ~APO_UDMA_MASK(chp->ch_channel); 352 353 /* setup DMA if needed */ 354 pciide_channel_dma_setup(cp); 355 356 for (drive = 0; drive < 2; drive++) { 357 drvp = &chp->ch_drive[drive]; 358 /* If no drive, skip */ 359 if ((drvp->drive_flags & DRIVE) == 0) 360 continue; 361 /* add timing values, setup DMA if needed */ 362 if (((drvp->drive_flags & DRIVE_DMA) == 0 && 363 (drvp->drive_flags & DRIVE_UDMA) == 0)) { 364 mode = drvp->PIO_mode; 365 goto pio; 366 } 367 if ((wdc->cap & WDC_CAPABILITY_UDMA) && 368 (drvp->drive_flags & DRIVE_UDMA)) { 369 /* use Ultra/DMA */ 370 drvp->drive_flags &= ~DRIVE_DMA; 371 udmatim_reg |= APO_UDMA_EN(chp->ch_channel, drive) | 372 APO_UDMA_EN_MTH(chp->ch_channel, drive); 373 switch (PCI_VENDOR(sc->sc_pci_id)) { 374 case PCI_VENDOR_VIATECH: 375 if (sc->sc_wdcdev.UDMA_cap == 6) { 376 /* 8233a */ 377 udmatim_reg |= APO_UDMA_TIME( 378 chp->ch_channel, 379 drive, 380 via_udma133_tim[drvp->UDMA_mode]); 381 } else if (sc->sc_wdcdev.UDMA_cap == 5) { 382 /* 686b */ 383 udmatim_reg |= APO_UDMA_TIME( 384 chp->ch_channel, 385 drive, 386 via_udma100_tim[drvp->UDMA_mode]); 387 } else if (sc->sc_wdcdev.UDMA_cap == 4) { 388 /* 596b or 686a */ 389 udmatim_reg |= APO_UDMA_CLK66( 390 chp->ch_channel); 391 udmatim_reg |= APO_UDMA_TIME( 392 chp->ch_channel, 393 drive, 394 via_udma66_tim[drvp->UDMA_mode]); 395 } else { 396 /* 596a or 586b */ 397 udmatim_reg |= APO_UDMA_TIME( 398 chp->ch_channel, 399 drive, 400 via_udma33_tim[drvp->UDMA_mode]); 401 } 402 break; 403 case PCI_VENDOR_AMD: 404 case PCI_VENDOR_NVIDIA: 405 udmatim_reg |= APO_UDMA_TIME(chp->ch_channel, 406 drive, amd7x6_udma_tim[drvp->UDMA_mode]); 407 break; 408 } 409 /* can use PIO timings, MW DMA unused */ 410 mode = drvp->PIO_mode; 411 } else { 412 /* use Multiword DMA, but only if revision is OK */ 413 drvp->drive_flags &= ~DRIVE_UDMA; 414 #ifndef PCIIDE_AMD756_ENABLEDMA 415 /* 416 * The workaround doesn't seem to be necessary 417 * with all drives, so it can be disabled by 418 * PCIIDE_AMD756_ENABLEDMA. It causes a hard hang if 419 * triggered. 420 */ 421 if (PCI_VENDOR(sc->sc_pci_id) == PCI_VENDOR_AMD && 422 sc->sc_pp->ide_product == 423 PCI_PRODUCT_AMD_PBC756_IDE && 424 AMD756_CHIPREV_DISABLEDMA(rev)) { 425 aprint_normal( 426 "%s:%d:%d: multi-word DMA disabled due " 427 "to chip revision\n", 428 sc->sc_wdcdev.sc_dev.dv_xname, 429 chp->ch_channel, drive); 430 mode = drvp->PIO_mode; 431 drvp->drive_flags &= ~DRIVE_DMA; 432 goto pio; 433 } 434 #endif 435 /* mode = min(pio, dma+2) */ 436 if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) 437 mode = drvp->PIO_mode; 438 else 439 mode = drvp->DMA_mode + 2; 440 } 441 idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); 442 443 pio: /* setup PIO mode */ 444 if (mode <= 2) { 445 drvp->DMA_mode = 0; 446 drvp->PIO_mode = 0; 447 mode = 0; 448 } else { 449 drvp->PIO_mode = mode; 450 drvp->DMA_mode = mode - 2; 451 } 452 datatim_reg |= 453 APO_DATATIM_PULSE(chp->ch_channel, drive, 454 apollo_pio_set[mode]) | 455 APO_DATATIM_RECOV(chp->ch_channel, drive, 456 apollo_pio_rec[mode]); 457 } 458 if (idedma_ctl != 0) { 459 /* Add software bits in status register */ 460 bus_space_write_1(sc->sc_dma_iot, cp->dma_iohs[IDEDMA_CTL], 0, 461 idedma_ctl); 462 } 463 pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc), datatim_reg); 464 pci_conf_write(sc->sc_pc, sc->sc_tag, APO_UDMA(sc), udmatim_reg); 465 WDCDEBUG_PRINT(("via_chip_map: APO_DATATIM=0x%x, APO_UDMA=0x%x\n", 466 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)), 467 pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), DEBUG_PROBE); 468 } 469 470 static void 471 via_sata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) 472 { 473 struct pciide_channel *cp; 474 pcireg_t interface = PCI_INTERFACE(pa->pa_class); 475 int channel; 476 bus_size_t cmdsize, ctlsize; 477 478 if (pciide_chipen(sc, pa) == 0) 479 return; 480 481 if (interface == 0) { 482 WDCDEBUG_PRINT(("via_sata_chip_map interface == 0\n"), 483 DEBUG_PROBE); 484 interface = PCIIDE_INTERFACE_BUS_MASTER_DMA | 485 PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1); 486 } 487 488 aprint_normal("%s: bus-master DMA support present", 489 sc->sc_wdcdev.sc_dev.dv_xname); 490 pciide_mapreg_dma(sc, pa); 491 aprint_normal("\n"); 492 493 if (sc->sc_dma_ok) { 494 sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA | WDC_CAPABILITY_DMA | 495 WDC_CAPABILITY_IRQACK; 496 sc->sc_wdcdev.irqack = pciide_irqack; 497 } 498 sc->sc_wdcdev.PIO_cap = 4; 499 sc->sc_wdcdev.DMA_cap = 2; 500 sc->sc_wdcdev.UDMA_cap = 6; 501 502 sc->sc_wdcdev.channels = sc->wdc_chanarray; 503 sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS; 504 sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 | 505 WDC_CAPABILITY_MODE; 506 sc->sc_wdcdev.set_modes = sata_setup_channel; 507 508 for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { 509 cp = &sc->pciide_channels[channel]; 510 if (pciide_chansetup(sc, channel, interface) == 0) 511 continue; 512 pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, 513 pciide_pci_intr); 514 } 515 } 516