/* You may notice we don't use this function on normal operation, * our, normal mdma function is supposed to be more precise */ static int pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) { int intf = pmac_ide_find(drive); int unit = (drive->select.all & 0x10) ? 1:0; int ret = 0; u32 *timings; if (intf < 0) return 1; timings = &pmac_ide[intf].timings[unit]; switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC case XFER_UDMA_4: case XFER_UDMA_3: case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: ret = set_timings_udma(intf, timings, speed); break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: case XFER_SW_DMA_2: case XFER_SW_DMA_1: case XFER_SW_DMA_0: ret = set_timings_mdma(intf, timings, speed); break; #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: case XFER_PIO_1: case XFER_PIO_0: pmac_ide_tuneproc(drive, speed & 0x07); break; default: ret = 1; } if (ret) return ret; ret = pmac_ide_do_setfeature(drive, speed); if (ret) return ret; pmac_ide_selectproc(drive); drive->current_speed = speed; return 0; }
/* Here we handle media bay devices */ static void idepmac_wake_bay(int i, unsigned long base) { int timeout; /* Reset timings */ pmac_ide_selectproc(&ide_hwifs[i].drives[0]); mdelay(10); timeout = 10000; while ((inb(base + 0x70) & BUSY_STAT) && timeout) { mdelay(1); --timeout; } }
static void idepmac_wake_disk(int i, unsigned long base) { struct device_node* np = pmac_ide[i].node; int j; /* Revive IDE disk and controller */ switch(pmac_ide[i].aapl_bus_id) { case 0: feature_set(np, FEATURE_IDE0_reset); feature_set(np, FEATURE_IOBUS_enable); mdelay(10); feature_set(np, FEATURE_IDE0_enable); mdelay(10); feature_clear(np, FEATURE_IDE0_reset); break; case 1: feature_set(np, FEATURE_IDE1_reset); feature_set(np, FEATURE_IOBUS_enable); mdelay(10); feature_set(np, FEATURE_IDE1_enable); mdelay(10); feature_clear(np, FEATURE_IDE1_reset); break; case 2: /* This one exists only for KL, I don't know about any enable bit */ feature_set(np, FEATURE_IDE2_reset); mdelay(10); feature_clear(np, FEATURE_IDE2_reset); break; } mdelay(IDE_WAKEUP_DELAY_MS); /* Reset timings */ pmac_ide_selectproc(&ide_hwifs[i].drives[0]); mdelay(10); /* Wait up to 10 seconds (enough for recent drives) */ for (j = 0; j < 100; j++) { int status; mdelay(100); status = inb(base + 0x70); if (!(status & BUSY_STAT)) break; } }
/* Calculate PIO timings */ static void pmac_ide_tuneproc(ide_drive_t *drive, byte pio) { ide_pio_data_t d; int i; u32 *timings; int accessTicks, recTicks; i = pmac_ide_find(drive); if (i < 0) return; pio = ide_get_best_pio_mode(drive, pio, 4, &d); accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time); if (drive->select.all & 0x10) timings = &pmac_ide[i].timings[1]; else timings = &pmac_ide[i].timings[0]; if (pmac_ide[i].kind == controller_kl_ata4) { /* The "ata-4" IDE controller of Core99 machines */ accessTicks = SYSCLK_TICKS_UDMA(ide_pio_timings[pio].active_time * 1000); recTicks = SYSCLK_TICKS_UDMA(d.cycle_time * 1000) - accessTicks; *timings = ((*timings) & 0x1FFFFFC00) | accessTicks | (recTicks << 5); } else { /* The old "ata-3" IDE controller */ accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time); if (accessTicks < 4) accessTicks = 4; recTicks = SYSCLK_TICKS(d.cycle_time) - accessTicks - 4; if (recTicks < 1) recTicks = 1; *timings = ((*timings) & 0xFFFFFF800) | accessTicks | (recTicks << 5); } #ifdef IDE_PMAC_DEBUG printk(KERN_ERR "ide_pmac: Set PIO timing for mode %d, reg: 0x%08x\n", pio, *timings); #endif if (drive->select.all == IN_BYTE(IDE_SELECT_REG)) pmac_ide_selectproc(drive); }
static int pmac_ide_check_dma(ide_drive_t *drive) { int ata4, udma, idx; struct hd_driveid *id = drive->id; int enable = 1; drive->using_dma = 0; idx = pmac_ide_find(drive); if (idx < 0) return 0; if (drive->media == ide_floppy) enable = 0; if (((id->capability & 1) == 0) && !check_drive_lists(drive, GOOD_DMA_DRIVE)) enable = 0; if (check_drive_lists(drive, BAD_DMA_DRIVE)) enable = 0; udma = 0; ata4 = (pmac_ide[idx].kind == controller_kl_ata4); if(enable) { if (ata4 && (drive->media == ide_disk) && (id->field_valid & 0x0004) && (id->dma_ultra & 0x17)) { /* UltraDMA modes. */ drive->using_dma = pmac_ide_udma_enable(drive, idx); } if (!drive->using_dma && (id->dma_mword & 0x0007)) { /* Normal MultiWord DMA modes. */ drive->using_dma = pmac_ide_mdma_enable(drive, idx); } /* Without this, strange things will happen on Keylargo-based * machines */ OUT_BYTE(0, IDE_CONTROL_REG); /* Apply settings to controller */ pmac_ide_selectproc(drive); } return 0; }
static void idepmac_wake_interface(int i, unsigned long base, int mediabay) { struct device_node* np = pmac_ide[i].node; if (!mediabay) { /* Revive IDE disk and controller */ switch(pmac_ide[i].aapl_bus_id) { case 0: feature_set(np, FEATURE_IDE0_reset); feature_set(np, FEATURE_IOBUS_enable); mdelay(10); feature_set(np, FEATURE_IDE0_enable); mdelay(10); feature_clear(np, FEATURE_IDE0_reset); break; case 1: feature_set(np, FEATURE_IDE1_reset); feature_set(np, FEATURE_IOBUS_enable); mdelay(10); feature_set(np, FEATURE_IDE1_enable); mdelay(10); feature_clear(np, FEATURE_IDE1_reset); break; case 2: /* This one exists only for KL, I don't know about any enable bit */ feature_set(np, FEATURE_IDE2_reset); mdelay(10); feature_clear(np, FEATURE_IDE2_reset); break; } } /* Reset timings */ pmac_ide_selectproc(&ide_hwifs[i].drives[0]); mdelay(10); }