viaide.c revision 1.9 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