static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) { unsigned int index = 0, cycle_time; u8 b; switch (pio) { case 6: /* set fast-devsel off */ case 7: /* set fast-devsel on */ b = get_cmd640_reg(CNTRL) & ~0x27; if (pio & 1) b |= 0x27; put_cmd640_reg(CNTRL, b); printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, (pio & 1) ? "en" : "dis"); return; case 8: /* set prefetch off */ case 9: /* set prefetch on */ set_prefetch_mode(drive, index, pio & 1); printk("%s: %sabled cmd640 prefetch\n", drive->name, (pio & 1) ? "en" : "dis"); return; } cycle_time = ide_pio_cycle_time(drive, pio); cmd640_set_mode(drive, index, pio, cycle_time); printk("%s: selected cmd640 PIO mode%d (%dns)", drive->name, pio, cycle_time); display_clocks(index); }
/* * Set PIO mode for the specified drive. * This function computes timing parameters * and sets controller registers accordingly. */ static void ali14xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { int driveNum; int time1, time2; u8 param1, param2, param3, param4; unsigned long flags; int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; const u8 pio = drive->pio_mode - XFER_PIO_0; struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); /* calculate timing, according to PIO mode */ time1 = ide_pio_cycle_time(drive, pio); time2 = t->active; param3 = param1 = (time2 * bus_speed + 999) / 1000; param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1; if (pio < 3) { param3 += 8; param4 += 8; } printk(KERN_DEBUG "%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n", drive->name, pio, time1, time2, param1, param2, param3, param4); /* stuff timing parameters into controller registers */ driveNum = (drive->hwif->index << 1) + (drive->dn & 1); spin_lock_irqsave(&ali14xx_lock, flags); outb_p(regOn, basePort); outReg(param1, regTab[driveNum].reg1); outReg(param2, regTab[driveNum].reg2); outReg(param3, regTab[driveNum].reg3); outReg(param4, regTab[driveNum].reg4); outb_p(regOff, basePort); spin_unlock_irqrestore(&ali14xx_lock, flags); }
/* * This routine writes into the chipset registers * PIO setup/active/recovery timings. */ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); unsigned long setup_count; unsigned int cycle_time; u8 arttim = 0; static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; cycle_time = ide_pio_cycle_time(drive, pio); program_cycle_times(drive, cycle_time, t->active); setup_count = quantize_timing(t->setup, 1000 / (ide_pci_clk ? ide_pci_clk : 33)); /* * The primary channel has individual address setup timing registers * for each drive and the hardware selects the slowest timing itself. * The secondary channel has one common register and we have to select * the slowest address setup timing ourselves. */ if (hwif->channel) { ide_drive_t *pair = ide_get_pair_dev(drive); ide_set_drivedata(drive, (void *)setup_count); if (pair) setup_count = max_t(u8, setup_count, (unsigned long)ide_get_drivedata(pair)); } if (setup_count > 5) /* shouldn't actually happen... */ setup_count = 5; cmdprintk("Final address setup count: %d\n", setup_count); /* * Program the address setup clocks into the ARTTIM registers. * Avoid clearing the secondary channel's interrupt bit. */ (void) pci_read_config_byte (dev, arttim_regs[drive->dn], &arttim); if (hwif->channel) arttim &= ~ARTTIM23_INTR_CH1; arttim &= ~0xc0; arttim |= setup_values[setup_count]; (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim); cmdprintk("Write 0x%02x to reg 0x%x\n", arttim, arttim_regs[drive->dn]); }
static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio) { unsigned int cycle_time; int is_slave = drive->dn & 1; ide_drive_t *mate; void __iomem *base = (void *)drive->hwif->dma_base; /* * Obtain the drive PIO data for tuning the Palm Chip registers */ cycle_time = ide_pio_cycle_time(drive, pio); mate = ide_get_pair_dev(drive); palm_bk3710_setpiomode(base, mate, is_slave, cycle_time, pio); }
static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) { int active_time, recovery_time; int active_cycles, recovery_cycles; int bus_speed = system_bus_clock(); if (pio) { unsigned int cycle_time; cycle_time = ide_pio_cycle_time(drive, pio); /* * Just like opti621.c we try to calculate the * actual cycle time for recovery and activity * according system bus speed. */ active_time = ide_pio_timings[pio].active_time; recovery_time = cycle_time - active_time - ide_pio_timings[pio].setup_time; /* * Cycle times should be Vesa bus cycles */ active_cycles = (active_time * bus_speed + 999) / 1000; recovery_cycles = (recovery_time * bus_speed + 999) / 1000; /* * Upper and lower limits */ if (active_cycles < 2) active_cycles = 2; if (recovery_cycles < 2) recovery_cycles = 2; if (active_cycles > 15) active_cycles = 15; if (recovery_cycles > 15) recovery_cycles = 0; /* 0==16 */ #ifdef DEBUG printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time); #endif return (u8)((recovery_cycles << 4) | active_cycles); } else { #ifdef DEBUG printk("ht6560b: drive %s setting pio=0\n", drive->name); #endif return HT_TIMING_DEFAULT; /* default setting */ } }
static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) { int active_time, recovery_time; int active_cycles, recovery_cycles; int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; if (pio) { unsigned int cycle_time; struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); cycle_time = ide_pio_cycle_time(drive, pio); /* */ active_time = t->active; recovery_time = cycle_time - active_time - t->setup; /* */ active_cycles = (active_time * bus_speed + 999) / 1000; recovery_cycles = (recovery_time * bus_speed + 999) / 1000; /* */ if (active_cycles < 2) active_cycles = 2; if (recovery_cycles < 2) recovery_cycles = 2; if (active_cycles > 15) active_cycles = 15; if (recovery_cycles > 15) recovery_cycles = 0; /* */ #ifdef DEBUG printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time); #endif return (u8)((recovery_cycles << 4) | active_cycles); } else { #ifdef DEBUG printk("ht6560b: drive %s setting pio=0\n", drive->name); #endif return HT_TIMING_DEFAULT; /* */ } }
/* * 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); }