static int set_timings_mdma(int intf, u32 *timings, byte speed) { int cycleTime, accessTime; int accessTicks, recTicks; /* Calculate accesstime and cycle time */ cycleTime = mdma_timings[speed & 0xf].cycleTime; accessTime = mdma_timings[speed & 0xf].accessTime; if ((pmac_ide[intf].kind == controller_ohare) && (cycleTime < 150)) cycleTime = 150; /* For ata-4 controller */ if (pmac_ide[intf].kind == controller_kl_ata4) { accessTicks = SYSCLK_TICKS_UDMA(accessTime * 1000); recTicks = SYSCLK_TICKS_UDMA(cycleTime * 1000) - accessTicks; *timings = ((*timings) & 0xffe003ff) | (accessTicks | (recTicks << 5)) << 10; } else { int halfTick = 0; int origAccessTime = accessTime; int origCycleTime = cycleTime; accessTicks = SYSCLK_TICKS(accessTime); if (accessTicks < 1) accessTicks = 1; accessTime = accessTicks * IDE_SYSCLK_NS; recTicks = SYSCLK_TICKS(cycleTime - accessTime) - 1; if (recTicks < 1) recTicks = 1; cycleTime = (recTicks + 1 + accessTicks) * IDE_SYSCLK_NS; /* KeyLargo ata-3 don't support the half-tick stuff */ if ((pmac_ide[intf].kind != controller_kl_ata3) && (accessTicks > 1) && ((accessTime - IDE_SYSCLK_NS/2) >= origAccessTime) && ((cycleTime - IDE_SYSCLK_NS) >= origCycleTime)) { halfTick = 1; accessTicks--; } *timings = ((*timings) & 0x7FF) | (accessTicks | (recTicks << 5) | (halfTick << 10)) << 11; } return 0; }
/* 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); }
/* * Calculate MDMA timings for all cells */ static void set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, u8 speed) { u16 *id = drive->id; int cycleTime, accessTime = 0, recTime = 0; unsigned accessTicks, recTicks; struct mdma_timings_t* tm = NULL; int i; /* Get default cycle time for mode */ switch(speed & 0xf) { case 0: cycleTime = 480; break; case 1: cycleTime = 150; break; case 2: cycleTime = 120; break; default: BUG(); break; } /* Check if drive provides explicit DMA cycle time */ if ((id[ATA_ID_FIELD_VALID] & 2) && id[ATA_ID_EIDE_DMA_TIME]) cycleTime = max_t(int, id[ATA_ID_EIDE_DMA_TIME], cycleTime); /* OHare limits according to some old Apple sources */ if ((intf_type == controller_ohare) && (cycleTime < 150)) cycleTime = 150; /* Get the proper timing array for this controller */ switch(intf_type) { case controller_sh_ata6: case controller_un_ata6: case controller_k2_ata6: break; case controller_kl_ata4: tm = mdma_timings_66; break; case controller_kl_ata3: tm = mdma_timings_33k; break; default: tm = mdma_timings_33; break; } if (tm != NULL) { /* Lookup matching access & recovery times */ i = -1; for (;;) { if (tm[i+1].cycleTime < cycleTime) break; i++; } cycleTime = tm[i].cycleTime; accessTime = tm[i].accessTime; recTime = tm[i].recoveryTime; #ifdef IDE_PMAC_DEBUG printk(KERN_ERR "%s: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n", drive->name, cycleTime, accessTime, recTime); #endif } switch(intf_type) { case controller_sh_ata6: { /* 133Mhz cell */ u32 tr = kauai_lookup_timing(shasta_mdma_timings, cycleTime); *timings = ((*timings) & ~TR_133_PIOREG_MDMA_MASK) | tr; *timings2 = (*timings2) & ~TR_133_UDMAREG_UDMA_EN; } break; case controller_un_ata6: case controller_k2_ata6: { /* 100Mhz cell */ u32 tr = kauai_lookup_timing(kauai_mdma_timings, cycleTime); *timings = ((*timings) & ~TR_100_PIOREG_MDMA_MASK) | tr; *timings2 = (*timings2) & ~TR_100_UDMAREG_UDMA_EN; } break; case controller_kl_ata4: /* 66Mhz cell */ accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); accessTicks = max(accessTicks, 0x1U); recTicks = SYSCLK_TICKS_66(recTime); recTicks = min(recTicks, 0x1fU); recTicks = max(recTicks, 0x3U); /* Clear out mdma bits and disable udma */ *timings = ((*timings) & ~(TR_66_MDMA_MASK | TR_66_UDMA_MASK)) | (accessTicks << TR_66_MDMA_ACCESS_SHIFT) | (recTicks << TR_66_MDMA_RECOVERY_SHIFT); break; case controller_kl_ata3: /* 33Mhz cell on KeyLargo */ accessTicks = SYSCLK_TICKS(accessTime); accessTicks = max(accessTicks, 1U); accessTicks = min(accessTicks, 0x1fU); accessTime = accessTicks * IDE_SYSCLK_NS; recTicks = SYSCLK_TICKS(recTime); recTicks = max(recTicks, 1U); recTicks = min(recTicks, 0x1fU); *timings = ((*timings) & ~TR_33_MDMA_MASK) | (accessTicks << TR_33_MDMA_ACCESS_SHIFT) | (recTicks << TR_33_MDMA_RECOVERY_SHIFT); break; default: { /* 33Mhz cell on others */ int halfTick = 0; int origAccessTime = accessTime; int origRecTime = recTime; accessTicks = SYSCLK_TICKS(accessTime); accessTicks = max(accessTicks, 1U); accessTicks = min(accessTicks, 0x1fU); accessTime = accessTicks * IDE_SYSCLK_NS; recTicks = SYSCLK_TICKS(recTime); recTicks = max(recTicks, 2U) - 1; recTicks = min(recTicks, 0x1fU); recTime = (recTicks + 1) * IDE_SYSCLK_NS; if ((accessTicks > 1) && ((accessTime - IDE_SYSCLK_NS/2) >= origAccessTime) && ((recTime - IDE_SYSCLK_NS/2) >= origRecTime)) { halfTick = 1; accessTicks--; } *timings = ((*timings) & ~TR_33_MDMA_MASK) | (accessTicks << TR_33_MDMA_ACCESS_SHIFT) | (recTicks << TR_33_MDMA_RECOVERY_SHIFT); if (halfTick) *timings |= TR_33_MDMA_HALFTICK; } } #ifdef IDE_PMAC_DEBUG printk(KERN_ERR "%s: Set MDMA timing for mode %d, reg: 0x%08x\n", drive->name, speed & 0xf, *timings); #endif }
/* * Old tuning functions (called on hdparm -p), sets up drive PIO timings */ static void pmac_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent); const u8 pio = drive->pio_mode - XFER_PIO_0; struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio); u32 *timings, t; unsigned accessTicks, recTicks; unsigned accessTime, recTime; unsigned int cycle_time; /* which drive is it ? */ timings = &pmif->timings[drive->dn & 1]; t = *timings; cycle_time = ide_pio_cycle_time(drive, pio); switch (pmif->kind) { case controller_sh_ata6: { /* 133Mhz cell */ u32 tr = kauai_lookup_timing(shasta_pio_timings, cycle_time); t = (t & ~TR_133_PIOREG_PIO_MASK) | tr; break; } case controller_un_ata6: case controller_k2_ata6: { /* 100Mhz cell */ u32 tr = kauai_lookup_timing(kauai_pio_timings, cycle_time); t = (t & ~TR_100_PIOREG_PIO_MASK) | tr; break; } case controller_kl_ata4: /* 66Mhz cell */ recTime = cycle_time - tim->active - tim->setup; recTime = max(recTime, 150U); accessTime = tim->active; accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); recTicks = SYSCLK_TICKS_66(recTime); recTicks = min(recTicks, 0x1fU); t = (t & ~TR_66_PIO_MASK) | (accessTicks << TR_66_PIO_ACCESS_SHIFT) | (recTicks << TR_66_PIO_RECOVERY_SHIFT); break; default: { /* 33Mhz cell */ int ebit = 0; recTime = cycle_time - tim->active - tim->setup; recTime = max(recTime, 150U); accessTime = tim->active; accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS(accessTime); accessTicks = min(accessTicks, 0x1fU); accessTicks = max(accessTicks, 4U); recTicks = SYSCLK_TICKS(recTime); recTicks = min(recTicks, 0x1fU); recTicks = max(recTicks, 5U) - 4; if (recTicks > 9) { recTicks--; /* guess, but it's only for PIO0, so... */ ebit = 1; } t = (t & ~TR_33_PIO_MASK) | (accessTicks << TR_33_PIO_ACCESS_SHIFT) | (recTicks << TR_33_PIO_RECOVERY_SHIFT); if (ebit) t |= TR_33_PIO_E; break; } } #ifdef IDE_PMAC_DEBUG printk(KERN_ERR "%s: Set PIO timing for mode %d, reg: 0x%08x\n", drive->name, pio, *timings); #endif *timings = t; pmac_ide_do_update_timings(drive); }
/* Calculate MultiWord DMA timings */ static int pmac_ide_mdma_enable(ide_drive_t *drive, int idx) { byte bits = drive->id->dma_mword & 0x07; byte feature = dma_bits_to_command(bits); u32 *timings; int cycleTime, accessTime; int accessTicks, recTicks; struct hd_driveid *id = drive->id; int ret; /* Set feature on drive */ printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, feature & 0xf); ret = pmac_ide_do_setfeature(drive, feature); if (ret) { printk(KERN_WARNING "%s: Failed !\n", drive->name); return 0; } if (!drive->init_speed) drive->init_speed = feature; /* which drive is it ? */ if (drive->select.all & 0x10) timings = &pmac_ide[idx].timings[1]; else timings = &pmac_ide[idx].timings[0]; /* Calculate accesstime and cycle time */ cycleTime = mdma_timings[feature & 0xf].cycleTime; accessTime = mdma_timings[feature & 0xf].accessTime; if ((id->field_valid & 2) && (id->eide_dma_time)) cycleTime = id->eide_dma_time; if ((pmac_ide[idx].kind == controller_ohare) && (cycleTime < 150)) cycleTime = 150; /* For ata-4 controller */ if (pmac_ide[idx].kind == controller_kl_ata4) { accessTicks = SYSCLK_TICKS_UDMA(accessTime * 1000); recTicks = SYSCLK_TICKS_UDMA(cycleTime * 1000) - accessTicks; *timings = ((*timings) & 0xffe003ff) | (accessTicks | (recTicks << 5)) << 10; } else { int halfTick = 0; int origAccessTime = accessTime; int origCycleTime = cycleTime; accessTicks = SYSCLK_TICKS(accessTime); if (accessTicks < 1) accessTicks = 1; accessTime = accessTicks * IDE_SYSCLK_NS; recTicks = SYSCLK_TICKS(cycleTime - accessTime) - 1; if (recTicks < 1) recTicks = 1; cycleTime = (recTicks + 1 + accessTicks) * IDE_SYSCLK_NS; /* KeyLargo ata-3 don't support the half-tick stuff */ if ((pmac_ide[idx].kind != controller_kl_ata3) && (accessTicks > 1) && ((accessTime - IDE_SYSCLK_NS/2) >= origAccessTime) && ((cycleTime - IDE_SYSCLK_NS) >= origCycleTime)) { halfTick = 1; accessTicks--; } *timings = ((*timings) & 0x7FF) | (accessTicks | (recTicks << 5) | (halfTick << 10)) << 11; } #ifdef IDE_PMAC_DEBUG printk(KERN_INFO "ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n", feature & 0xf, *timings); #endif drive->current_speed = feature; return 1; }