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