Subject: possible fix for VIA apollo problem
To: None <port-cobalt@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: port-cobalt
Date: 10/15/2000 15:50:20
--EeQfGwPcQSOJBaQU
Content-Type: text/plain; charset=us-ascii

Hi,
attached is a patch that may help peoples having problems with the VT82C686
PCI IDE controllers: some of these controllers may support Ultra/66, it also
seems that some of them don't support Ultra/33 at all. This patch is an attempt
to detect such cases.
For peoples who have such controllers: please test this patch, if possible
with wdcdebug_pciide_mask set to DEBUG_PROBE, and send me the dmesg output.
Thanks !

--
Manuel Bouyer <bouyer@antioche.eu.org>
--

--EeQfGwPcQSOJBaQU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

--- pciide_apollo_reg.h.orig	Sun Oct 15 15:32:31 2000
+++ pciide_apollo_reg.h	Sun Oct 15 15:34:29 2000
@@ -80,13 +80,15 @@
 /* Ultra-DMA/33 control (586A/B only) */
 #define APO_UDMA 0x50
 #define AP0_UDMA_MASK(channel) (0xffff << ((1 - (channel)) << 4))
-#define APO_UDMA_TIME(channel, drive, x) (((x) & 0x3) << \
+#define APO_UDMA_TIME(channel, drive, x) (((x) & 0x03) << \
 	(((1 - (channel)) << 4) + ((1 - (drive)) << 3)))
 #define APO_UDMA_PIO_MODE(channel, drive) (0x20 << \
 	(((1 - (channel)) << 4) + ((1 - (drive)) << 3)))
 #define APO_UDMA_EN(channel, drive) (0x40 << \
 	(((1 - (channel)) << 4) + ((1 - (drive)) << 3)))
 #define APO_UDMA_EN_MTH(channel, drive) (0x80 << \
+	(((1 - (channel)) << 4) + ((1 - (drive)) << 3)))
+#define APO_UDMA_CLK66(channel, drive) (0x08 << \
 	(((1 - (channel)) << 4) + ((1 - (drive)) << 3)))
 
 static int8_t apollo_udma_tim[] = {0x03, 0x02, 0x00};
--- pciide.c.orig	Sun Oct 15 15:29:31 2000
+++ pciide.c	Sun Oct 15 15:45:56 2000
@@ -1888,7 +1888,7 @@
 	pcireg_t interface = PCI_INTERFACE(pa->pa_class);
 	int rev = PCI_REVISION(pa->pa_class);
 	int channel;
-	u_int32_t ideconf;
+	u_int32_t ideconf, udma_conf, old_udma_conf;
 	bus_size_t cmdsize, ctlsize;
 
 	if (pciide_chipen(sc, pa) == 0)
@@ -1913,13 +1913,37 @@
 	sc->sc_wdcdev.channels = sc->wdc_chanarray;
 	sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
 
+	old_udma_conf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA);
 	WDCDEBUG_PRINT(("apollo_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),
 	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC),
 	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM),
-	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA)),
+	    old_udma_conf),
 	    DEBUG_PROBE);
+	pci_conf_write(sc->sc_pc, sc->sc_tag,
+	    old_udma_conf | (APO_UDMA_PIO_MODE(0, 0) | APO_UDMA_EN(0, 0) |
+	    APO_UDMA_EN_MTH(0, 0) | APO_UDMA_CLK66(0, 0)),
+	    APO_UDMA);
+	udma_conf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA);
+	WDCDEBUG_PRINT(("apollo_chip_map: APO_UDMA now 0x%x\n", udma_conf),
+	    DEBUG_PROBE);
+	if ((udma_conf & (APO_UDMA_PIO_MODE(0, 0) | APO_UDMA_EN(0, 0) |
+	    APO_UDMA_EN_MTH(0, 0))) ==
+	    (APO_UDMA_PIO_MODE(0, 0) | APO_UDMA_EN(0, 0) |
+	    APO_UDMA_EN_MTH(0, 0))) {
+		if ((udma_conf & APO_UDMA_CLK66(0, 0)) ==
+		    APO_UDMA_CLK66(0, 0)) {
+			printf("%s: Ultra/66 capable\n",
+			    sc->sc_wdcdev.sc_dev.dv_xname);
+		} else {
+			printf("%s: Ultra/33 capable\n",
+			    sc->sc_wdcdev.sc_dev.dv_xname);
+		}
+	} else {
+		sc->sc_wdcdev.cap &= ~WDC_CAPABILITY_UDMA;
+	}
+	pci_conf_write(sc->sc_pc, sc->sc_tag, old_udma_conf, APO_UDMA);
 
 	for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
 		cp = &sc->pciide_channels[channel];

--EeQfGwPcQSOJBaQU--