From 295ed775957a5669d2b37728f6a0650689623740 Mon Sep 17 00:00:00 2001 From: scw Date: Wed, 7 Jun 2000 20:42:52 +0000 Subject: [PATCH] The OPTi controller supports a 32-bit dataport after all. Also detect when the chip is sitting on a 25MHz PCIbus and set the timing registers accordingly. --- sys/dev/pci/pciide.c | 23 ++++++++++++++--------- sys/dev/pci/pciide_opti_reg.h | 27 +++++++++++++++++++++------ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c index 651fc2ce766e..7594ad1ff444 100644 --- a/sys/dev/pci/pciide.c +++ b/sys/dev/pci/pciide.c @@ -1,4 +1,4 @@ -/* $NetBSD: pciide.c,v 1.65 2000/06/07 04:31:49 thorpej Exp $ */ +/* $NetBSD: pciide.c,v 1.66 2000/06/07 20:42:52 scw Exp $ */ /* @@ -2940,7 +2940,8 @@ opti_chip_map(sc, pa) pciide_mapreg_dma(sc, pa); printf("\n"); - sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_MODE; + sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 | + WDC_CAPABILITY_MODE; sc->sc_wdcdev.PIO_cap = 4; if (sc->sc_dma_ok) { sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA; @@ -2985,7 +2986,7 @@ opti_setup_channel(chp) struct ata_drive_datas *drvp; struct pciide_channel *cp = (struct pciide_channel*)chp; struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; - int drive; + int drive, spd; int mode[2]; u_int8_t rv, mr; @@ -3001,6 +3002,10 @@ opti_setup_channel(chp) /* Prime the control register before setting timing values */ opti_write_config(chp, OPTI_REG_CONTROL, OPTI_CONTROL_DISABLE); + /* Determine the clockrate of the PCIbus the chip is attached to */ + spd = (int) opti_read_config(chp, OPTI_REG_STRAP); + spd &= OPTI_STRAP_PCI_SPEED_MASK; + /* setup DMA if needed */ pciide_channel_dma_setup(cp); @@ -3030,14 +3035,14 @@ opti_setup_channel(chp) mode[drive] = drvp->PIO_mode; if (drive && mode[0] >= 0 && - (opti_tim_as[mode[0]] != opti_tim_as[mode[1]])) { + (opti_tim_as[spd][mode[0]] != opti_tim_as[spd][mode[1]])) { /* * Can't have two drives using different values * for `Address Setup Time'. * Slow down the faster drive to compensate. */ - int d; - d = (opti_tim_as[mode[0]] > opti_tim_as[mode[1]])?0:1; + int d = (opti_tim_as[spd][mode[0]] > + opti_tim_as[spd][mode[1]]) ? 0 : 1; mode[d] = mode[1-d]; chp->ch_drive[d].PIO_mode = chp->ch_drive[1-d].PIO_mode; @@ -3052,13 +3057,13 @@ opti_setup_channel(chp) continue; /* Set the Address Setup Time and select appropriate index */ - rv = opti_tim_as[m] << OPTI_MISC_ADDR_SETUP_SHIFT; + rv = opti_tim_as[spd][m] << OPTI_MISC_ADDR_SETUP_SHIFT; rv |= OPTI_MISC_INDEX(drive); opti_write_config(chp, OPTI_REG_MISC, mr | rv); /* Set the pulse width and recovery timing parameters */ - rv = opti_tim_cp[m] << OPTI_PULSE_WIDTH_SHIFT; - rv |= opti_tim_rt[m] << OPTI_RECOVERY_TIME_SHIFT; + rv = opti_tim_cp[spd][m] << OPTI_PULSE_WIDTH_SHIFT; + rv |= opti_tim_rt[spd][m] << OPTI_RECOVERY_TIME_SHIFT; opti_write_config(chp, OPTI_REG_READ_CYCLE_TIMING, rv); opti_write_config(chp, OPTI_REG_WRITE_CYCLE_TIMING, rv); diff --git a/sys/dev/pci/pciide_opti_reg.h b/sys/dev/pci/pciide_opti_reg.h index d08398edd071..800ebc6a6581 100644 --- a/sys/dev/pci/pciide_opti_reg.h +++ b/sys/dev/pci/pciide_opti_reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: pciide_opti_reg.h,v 1.1 2000/05/27 17:18:41 scw Exp $ */ +/* $NetBSD: pciide_opti_reg.h,v 1.2 2000/06/07 20:42:53 scw Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -159,9 +159,24 @@ opti_write_config(struct channel_softc *chp, int reg, u_int8_t val) /* * These are the timing register values for the various IDE modes - * supported by the OPTi chip when the PCIbus is running at 33MHz. + * supported by the OPTi chip. The first index of the two-dimensional + * arrays is used for a 33MHz PCIbus, the second for a 25MHz PCIbus. */ -static u_int8_t opti_tim_cp[] = {5, 4, 3, 2, 2, 7, 2, 2}; /* Command Pulse */ -static u_int8_t opti_tim_rt[] = {9, 4, 0, 0, 0, 6, 0, 0}; /* Recovery Time */ -static u_int8_t opti_tim_em[] = {0, 0, 0, 1, 2, 0, 1 ,2}; /* Enhanced Mode */ -static u_int8_t opti_tim_as[] = {2, 1, 1, 1, 0, 0, 0, 0}; /* Address Setup */ +static u_int8_t opti_tim_cp[2][8] = { /* Command Pulse */ + {5, 4, 3, 2, 2, 7, 2, 2}, + {4, 3, 2, 2, 1, 5, 2, 1} +}; + +static u_int8_t opti_tim_rt[2][8] = { /* Recovery Time */ + {9, 4, 0, 0, 0, 6, 0, 0}, + {6, 2, 0, 0, 0, 4, 0, 0} +}; + +static u_int8_t opti_tim_as[2][8] = { /* Address Setup */ + {2, 1, 1, 1, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0} +}; + +static u_int8_t opti_tim_em[8] = { /* Enhanced Mode */ + 0, 0, 0, 1, 2, 0, 1 ,2 +};