summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale S. Rahn <rahnds@cvs.openbsd.org>2000-09-08 05:43:57 +0000
committerDale S. Rahn <rahnds@cvs.openbsd.org>2000-09-08 05:43:57 +0000
commit196cc87073cb5a4bbcebe6cfed5bd1e8eb50bd8c (patch)
tree245f799eb15646fac964a32a09dca1b23f0baf4a
parent3bb43b8d159d25ed6cd3149a51721f6666e963ed (diff)
Modify ata timing parameters, gives signficant boost in disk speed.
From NetBSD.
-rw-r--r--sys/arch/powerpc/mac/wdc_obio.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/sys/arch/powerpc/mac/wdc_obio.c b/sys/arch/powerpc/mac/wdc_obio.c
index 4fb24ad53e3..d67a694844e 100644
--- a/sys/arch/powerpc/mac/wdc_obio.c
+++ b/sys/arch/powerpc/mac/wdc_obio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc_obio.c,v 1.5 2000/05/04 03:48:57 rahnds Exp $ */
+/* $OpenBSD: wdc_obio.c,v 1.6 2000/09/08 05:43:56 rahnds Exp $ */
/* $NetBSD: wdc_obio.c,v 1.4 1999/06/14 08:53:06 tsubai Exp $ */
/*-
@@ -48,6 +48,7 @@
#include <machine/autoconf.h>
#include <dev/ata/atavar.h>
+#include <dev/ata/atareg.h>
#include <dev/ic/wdcvar.h>
#include <powerpc/mac/dbdma.h>
@@ -107,6 +108,7 @@ struct cfdriver wdc_cd = {
static int wdc_obio_dma_init __P((void *, int, int, void *, size_t, int));
static void wdc_obio_dma_start __P((void *, int, int, int));
static int wdc_obio_dma_finish __P((void *, int, int, int));
+static void adjust_timing __P((struct channel_softc *));
int
wdc_obio_probe(parent, match, aux)
@@ -214,6 +216,76 @@ wdc_obio_attach(parent, self, aux)
}
wdcattach(chp);
+
+ /* modify DMA access timings */
+ if (use_dma)
+ adjust_timing(chp);
+}
+
+/* Multiword DMA transfer timings */
+static struct {
+ int cycle; /* minimum cycle time [ns] */
+ int active; /* minimum command active time [ns] */
+} dma_timing[3] = {
+ 480, 215, /* Mode 0 */
+ 150, 80, /* Mode 1 */
+ 120, 70, /* Mode 2 */
+};
+
+#define TIME_TO_TICK(time) howmany((time), 30)
+
+#define CONFIG_REG (0x200) /* IDE access timing register */
+
+void
+adjust_timing(chp)
+ struct channel_softc *chp;
+{
+ struct ataparams params;
+ struct ata_drive_datas *drvp = &chp->ch_drive[0]; /* XXX */
+ u_int conf;
+ int mode;
+ int cycle, active, min_cycle, min_active;
+ int cycle_tick, act_tick, inact_tick, half_tick;
+
+ if (ata_get_params(drvp, AT_POLL, &params) != CMD_OK)
+ return;
+
+ for (mode = 2; mode >= 0; mode--)
+ if (params.atap_dmamode_act & (1 << mode))
+ goto found;
+
+ /* No active DMA mode is found... Do nothing. */
+ return;
+
+found:
+ min_cycle = dma_timing[mode].cycle;
+ min_active = dma_timing[mode].active;
+
+#ifdef notyet
+ /* Minimum cycle time is 150ns on ohare. */
+ if (ohare && params.atap_dmatiming_recom < 150)
+ params.atap_dmatiming_recom = 150;
+#endif
+ cycle = max(min_cycle, params.atap_dmatiming_recom);
+ active = min_active + (cycle - min_cycle); /* XXX */
+
+ cycle_tick = TIME_TO_TICK(cycle);
+ act_tick = TIME_TO_TICK(active);
+ inact_tick = cycle_tick - act_tick - 1;
+ if (inact_tick < 1)
+ inact_tick = 1;
+ half_tick = 0; /* XXX */
+#if 0
+ conf = bus_space_read_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG);
+ printf("conf = 0x%x, cyc = %d (%d ns), act = %d (%d ns), inact = %d\n",
+ conf, 0, 0, ((conf >> 11) & 0x1f), 0, ((conf >> 16) & 0x1f));
+#endif
+ conf = (half_tick << 21) | (inact_tick << 16) | (act_tick << 11);
+ bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG, conf);
+#if 0
+ printf("conf = 0x%x, cyc = %d (%d ns), act = %d (%d ns), inact = %d\n",
+ conf, cycle_tick, cycle, act_tick, active, inact_tick);
+#endif
}
static int