void wdc_obio_ata4_adjust_timing(struct channel_softc *chp) { struct ata_drive_datas *drvp; u_int conf; int drive; int piomode = -1, dmamode = -1; int min_cycle, min_active; int cycle_tick, act_tick, inact_tick; int udmamode = -1; for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; if ((drvp->drive_flags & DRIVE) == 0) continue; if (piomode == -1 || piomode > drvp->PIO_mode) piomode = drvp->PIO_mode; if (drvp->drive_flags & DRIVE_DMA) if (dmamode == -1 || dmamode > drvp->DMA_mode) dmamode = drvp->DMA_mode; if (drvp->drive_flags & DRIVE_UDMA) { if (udmamode == -1 || udmamode > drvp->UDMA_mode) udmamode = drvp->UDMA_mode; } else udmamode = -2; } if (piomode == -1) return; /* No drive */ for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; if (drvp->drive_flags & DRIVE) { drvp->PIO_mode = piomode; if (drvp->drive_flags & DRIVE_DMA) drvp->DMA_mode = dmamode; if (drvp->drive_flags & DRIVE_UDMA) { if (udmamode == -2) drvp->drive_flags &= ~DRIVE_UDMA; else drvp->UDMA_mode = udmamode; } } } if (udmamode == -2) udmamode = -1; min_cycle = pio_timing[piomode].cycle; min_active = pio_timing[piomode].active; cycle_tick = ATA4_TIME_TO_TICK(min_cycle); act_tick = ATA4_TIME_TO_TICK(min_active); inact_tick = cycle_tick - act_tick; /* mask: 0x000003ff */ conf = (inact_tick << 5) | act_tick; if (dmamode != -1) { /* there are active DMA mode */ min_cycle = dma_timing[dmamode].cycle; min_active = dma_timing[dmamode].active; cycle_tick = ATA4_TIME_TO_TICK(min_cycle); act_tick = ATA4_TIME_TO_TICK(min_active); inact_tick = cycle_tick - act_tick; /* mask: 0x001ffc00 */ conf |= (act_tick << 10) | (inact_tick << 15); } if (udmamode != -1) { min_cycle = udma_timing[udmamode].cycle; min_active = udma_timing[udmamode].active; act_tick = ATA4_TIME_TO_TICK(min_active); cycle_tick = ATA4_TIME_TO_TICK(min_cycle); /* mask: 0x1ff00000 */ conf |= (cycle_tick << 21) | (act_tick << 25) | 0x100000; } bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG, conf); #if 0 printf("ata4 conf = 0x%x, cyc = %d (%d ns), act = %d (%d ns), inact = %d\n", conf, cycle_tick, min_cycle, act_tick, min_active, inact_tick); #endif }
void ata4_adjust_timing(struct ata_channel *chp) { struct wdc_obio_softc *sc = (struct wdc_obio_softc *)chp->ch_atac; int drive; int min_cycle = 0, min_active = 0; int cycle_tick = 0, act_tick = 0, inact_tick = 0; for (drive = 0; drive < 2; drive++) { u_int conf = 0; struct ata_drive_datas *drvp; drvp = &chp->ch_drive[drive]; /* set up pio mode timings */ if (drvp->drive_type != ATA_DRIVET_NONE) { int piomode = drvp->PIO_mode; min_cycle = pio_timing[piomode].cycle; min_active = pio_timing[piomode].active; cycle_tick = ATA4_TIME_TO_TICK(min_cycle); act_tick = ATA4_TIME_TO_TICK(min_active); inact_tick = cycle_tick - act_tick; /* mask: 0x000003ff */ conf |= (inact_tick << 5) | act_tick; } /* set up dma mode timings */ if (drvp->drive_flags & ATA_DRIVE_DMA) { int dmamode = drvp->DMA_mode; min_cycle = dma_timing[dmamode].cycle; min_active = dma_timing[dmamode].active; cycle_tick = ATA4_TIME_TO_TICK(min_cycle); act_tick = ATA4_TIME_TO_TICK(min_active); inact_tick = cycle_tick - act_tick; /* mask: 0x001ffc00 */ conf |= (act_tick << 10) | (inact_tick << 15); } /* set up udma mode timings */ if (drvp->drive_flags & ATA_DRIVE_UDMA) { int udmamode = drvp->UDMA_mode; min_cycle = udma_timing[udmamode].cycle; min_active = udma_timing[udmamode].active; act_tick = ATA4_TIME_TO_TICK(min_active); cycle_tick = ATA4_TIME_TO_TICK(min_cycle); /* mask: 0x1ff00000 */ conf |= (cycle_tick << 21) | (act_tick << 25) | 0x100000; } #ifdef DEBUG if (conf) { printf("ata4 conf[%d] = 0x%x, cyc = %d (%d ns), act = %d (%d ns), inact = %d\n", drive, conf, cycle_tick, min_cycle, act_tick, min_active, inact_tick); } #endif sc->sc_dmaconf[drive] = conf; } sc->sc_wdcdev.select = 0; if (sc->sc_dmaconf[0]) { wdc_obio_select(chp,0); if (sc->sc_dmaconf[1] && (sc->sc_dmaconf[0] != sc->sc_dmaconf[1])) { sc->sc_wdcdev.select = wdc_obio_select; } } else if (sc->sc_dmaconf[1]) { wdc_obio_select(chp,1); } }