summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/pciide.c83
-rw-r--r--sys/dev/pci/pciide_apollo_reg.h7
-rw-r--r--sys/dev/pci/pciide_piix_reg.h10
3 files changed, 83 insertions, 17 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c
index 3e713dcf53d..18207613f78 100644
--- a/sys/dev/pci/pciide.c
+++ b/sys/dev/pci/pciide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide.c,v 1.39 2000/12/08 14:44:57 millert Exp $ */
+/* $OpenBSD: pciide.c,v 1.40 2001/01/08 19:54:09 jeremy Exp $ */
/* $NetBSD: pciide.c,v 1.48 1999/11/28 20:05:18 bouyer Exp $ */
/*
@@ -378,19 +378,19 @@ const struct pciide_product_desc pciide_acer_products[] = {
const struct pciide_product_desc pciide_promise_products[] = {
{ PCI_PRODUCT_PROMISE_PDC20246,
- IDE_PCI_CLASS_OVERRIDE|IDE_16BIT_IOSPACE,
+ IDE_PCI_CLASS_OVERRIDE,
pdc202xx_chip_map,
},
{ PCI_PRODUCT_PROMISE_PDC20262,
- IDE_PCI_CLASS_OVERRIDE|IDE_16BIT_IOSPACE,
+ IDE_PCI_CLASS_OVERRIDE,
pdc202xx_chip_map,
},
{ PCI_PRODUCT_PROMISE_PDC20265,
- IDE_PCI_CLASS_OVERRIDE|IDE_16BIT_IOSPACE,
+ IDE_PCI_CLASS_OVERRIDE,
pdc202xx_chip_map,
},
{ PCI_PRODUCT_PROMISE_PDC20267,
- IDE_PCI_CLASS_OVERRIDE|IDE_16BIT_IOSPACE,
+ IDE_PCI_CLASS_OVERRIDE,
pdc202xx_chip_map,
}
};
@@ -1396,9 +1396,11 @@ piix_chip_map(sc, pa)
sc->sc_wdcdev.DMA_cap = 2;
switch (sc->sc_pp->ide_product) {
case PCI_PRODUCT_INTEL_82801AA_IDE:
- case PCI_PRODUCT_INTEL_82801BA_IDE:
sc->sc_wdcdev.UDMA_cap = 4;
break;
+ case PCI_PRODUCT_INTEL_82801BA_IDE:
+ sc->sc_wdcdev.UDMA_cap = 5;
+ break;
default:
sc->sc_wdcdev.UDMA_cap = 2;
break;
@@ -1640,8 +1642,25 @@ piix3_4_setup_channel(chp)
sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BA_IDE ) {
ideconf |= PIIX_CONFIG_PINGPONG;
}
- if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AA_IDE ||
- sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BA_IDE ) {
+ if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BA_IDE) {
+ /* setup Ultra/100 */
+ if (drvp->UDMA_mode > 2 &&
+ (ideconf & PIIX_CONFIG_CR(channel, drive)) == 0)
+ drvp->UDMA_mode = 2;
+ if (drvp->UDMA_mode > 4) {
+ ideconf |= PIIX_CONFIG_UDMA100(channel, drive);
+ } else {
+ ideconf &= ~PIIX_CONFIG_UDMA100(channel, drive);
+ if (drvp->UDMA_mode > 2) {
+ ideconf |= PIIX_CONFIG_UDMA66(channel,
+ drive);
+ } else {
+ ideconf &= ~PIIX_CONFIG_UDMA66(channel,
+ drive);
+ }
+ }
+ }
+ if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AA_IDE ) {
/* setup Ultra/66 */
if (drvp->UDMA_mode > 2 &&
(ideconf & PIIX_CONFIG_CR(channel, drive)) == 0)
@@ -1957,7 +1976,7 @@ apollo_chip_map(sc, pa)
pcireg_t interface = PCI_INTERFACE(pa->pa_class);
pcireg_t 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)
@@ -1981,14 +2000,37 @@ apollo_chip_map(sc, pa)
pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
+ 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)),
+ 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)) ==
+ APO_UDMA_CLK66(0)) {
+ printf("%s: Ultra/66 capable\n",
+ sc->sc_wdcdev.sc_dev.dv_xname);
+ sc->sc_wdcdev.UDMA_cap = 4;
+ }
+ } 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];
if (pciide_chansetup(sc, channel, interface) == 0)
@@ -2040,6 +2082,24 @@ apollo_setup_channel(chp)
/* setup DMA if needed */
pciide_channel_dma_setup(cp);
+ /*
+ * We can't mix Ultra/33 and Ultra/66 on the same channel, so
+ * downgrade to Ultra/33 if needed
+ */
+ if ((chp->ch_drive[0].drive_flags & DRIVE_UDMA) &&
+ (chp->ch_drive[1].drive_flags & DRIVE_UDMA)) {
+ /* both drives UDMA */
+ if (chp->ch_drive[0].UDMA_mode > 2 &&
+ chp->ch_drive[1].UDMA_mode <= 2) {
+ /* drive 0 Ultra/66, drive 1 Ultra/33 */
+ chp->ch_drive[0].UDMA_mode = 2;
+ } else if (chp->ch_drive[1].UDMA_mode > 2 &&
+ chp->ch_drive[0].UDMA_mode <= 2) {
+ /* drive 1 Ultra/66, drive 0 Ultra/33 */
+ chp->ch_drive[1].UDMA_mode = 2;
+ }
+ }
+
for (drive = 0; drive < 2; drive++) {
drvp = &chp->ch_drive[drive];
/* If no drive, skip */
@@ -2059,6 +2119,9 @@ apollo_setup_channel(chp)
APO_UDMA_EN_MTH(chp->channel, drive) |
APO_UDMA_TIME(chp->channel, drive,
apollo_udma_tim[drvp->UDMA_mode]);
+ if (drvp->UDMA_mode > 2)
+ udmatim_reg |=
+ APO_UDMA_CLK66(chp->channel);
/* can use PIO timings, MW DMA unused */
mode = drvp->PIO_mode;
} else {
diff --git a/sys/dev/pci/pciide_apollo_reg.h b/sys/dev/pci/pciide_apollo_reg.h
index 7464142bbda..89738b61206 100644
--- a/sys/dev/pci/pciide_apollo_reg.h
+++ b/sys/dev/pci/pciide_apollo_reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide_apollo_reg.h,v 1.2 2000/06/05 09:18:10 chris Exp $ */
+/* $OpenBSD: pciide_apollo_reg.h,v 1.3 2001/01/08 19:54:09 jeremy Exp $ */
/* $NetBSD: pciide_apollo_reg.h,v 1.4 1998/12/16 12:48:46 bouyer Exp $ */
/*
@@ -86,7 +86,7 @@
/* misc timings control */
#define APO_MISCTIM 0x4c
-/* Ultra-DMA/33 control (586A/B only) */
+/* UltraDMA control (586A/B and higher only) */
#define APO_UDMA 0x50
#define AP0_UDMA_MASK(channel) (0xffff << ((1 - (channel)) << 4))
#define APO_UDMA_TIME(channel, drive, x) (((x) & 0x3) << \
@@ -97,7 +97,8 @@
(((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) (0x08 << ((1 - (channel)) << 4))
-static int8_t apollo_udma_tim[] = {0x03, 0x02, 0x00};
+static int8_t apollo_udma_tim[] = {0x03, 0x02, 0x00, 0x02, 0x00};
static int8_t apollo_pio_set[] = {0x0a, 0x0a, 0x0a, 0x02, 0x02};
static int8_t apollo_pio_rec[] = {0x08, 0x08, 0x08, 0x02, 0x00};
diff --git a/sys/dev/pci/pciide_piix_reg.h b/sys/dev/pci/pciide_piix_reg.h
index 38d45026b84..97bff704ad4 100644
--- a/sys/dev/pci/pciide_piix_reg.h
+++ b/sys/dev/pci/pciide_piix_reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide_piix_reg.h,v 1.2 1999/10/04 22:54:18 deraadt Exp $ */
+/* $OpenBSD: pciide_piix_reg.h,v 1.3 2001/01/08 19:54:09 jeremy Exp $ */
/* $NetBSD: pciide_piix_reg.h,v 1.2 1998/10/12 16:09:21 bouyer Exp $ */
/*
@@ -100,13 +100,15 @@
(((x) << ((channel * 8) + (drive * 4))) << PIIX_UDMATIM_SHIFT)
/*
- * IDE config register (ICH/ICH0 only)
+ * IDE config register (ICH/ICH0/ICH2 only)
*/
#define PIIX_CONFIG 0x54
#define PIIX_CONFIG_PINGPONG 0x0400
-/* The following are only for 82801AA (ICH) */
+/* The following are only for 82801AA (ICH) and 82801BA (ICH2) */
#define PIIX_CONFIG_CR(channel, drive) (0x0010 << ((channel) * 2 + (drive)))
#define PIIX_CONFIG_UDMA66(channel, drive) (0x0001 << ((channel) * 2 + (drive)))
+/* The following are only for the 82801BA (ICH2) */
+#define PIIX_CONFIG_UDMA100(channel, drive) (0x1000 << ((channel) * 2 + (drive)))
/*
* these tables define the differents values to upload to the
@@ -117,5 +119,5 @@ static int8_t piix_isp_pio[] = {0x00, 0x00, 0x01, 0x02, 0x02};
static int8_t piix_rtc_pio[] = {0x00, 0x00, 0x00, 0x01, 0x03};
static int8_t piix_isp_dma[] = {0x00, 0x02, 0x02};
static int8_t piix_rtc_dma[] = {0x00, 0x02, 0x03};
-static int8_t piix4_sct_udma[] = {0x00, 0x01, 0x02, 0x01, 0x02};
+static int8_t piix4_sct_udma[] = {0x00, 0x01, 0x02, 0x01, 0x02, 0x01};