예제 #1
0
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);
}
예제 #2
0
파일: ali14xx.c 프로젝트: ChineseDr/linux
/*
 * 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);
}
예제 #3
0
/*
 * 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]);
}
예제 #4
0
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);
}
예제 #5
0
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 */
	}
}
예제 #6
0
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;    /*                 */
	}
}
예제 #7
0
파일: pmac.c 프로젝트: AK101111/linux
/*
 * 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);
}