diff options
author | Dale S. Rahn <rahnds@cvs.openbsd.org> | 2000-09-08 05:43:57 +0000 |
---|---|---|
committer | Dale S. Rahn <rahnds@cvs.openbsd.org> | 2000-09-08 05:43:57 +0000 |
commit | 196cc87073cb5a4bbcebe6cfed5bd1e8eb50bd8c (patch) | |
tree | 245f799eb15646fac964a32a09dca1b23f0baf4a | |
parent | 3bb43b8d159d25ed6cd3149a51721f6666e963ed (diff) |
Modify ata timing parameters, gives signficant boost in disk speed.
From NetBSD.
-rw-r--r-- | sys/arch/powerpc/mac/wdc_obio.c | 74 |
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, ¶ms) != 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 |