Beispiel #1
0
static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
			    u8 pio_mode, unsigned int cycle_time)
{
	struct ide_timing *t;
	int setup_time, active_time, recovery_time, clock_time;
	u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
	int bus_speed;

	if (cmd640_vlb)
		bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
	else
		bus_speed = ide_pci_clk ? ide_pci_clk : 33;

	if (pio_mode > 5)
		pio_mode = 5;

	t = ide_timing_find_mode(XFER_PIO_0 + pio_mode);
	setup_time  = t->setup;
	active_time = t->active;

	recovery_time = cycle_time - (setup_time + active_time);
	clock_time = 1000 / bus_speed;
	cycle_count = DIV_ROUND_UP(cycle_time, clock_time);

	setup_count = DIV_ROUND_UP(setup_time, clock_time);

	active_count = DIV_ROUND_UP(active_time, clock_time);
	if (active_count < 2)
		active_count = 2; 

	recovery_count = DIV_ROUND_UP(recovery_time, clock_time);
	recovery_count2 = cycle_count - (setup_count + active_count);
	if (recovery_count2 > recovery_count)
		recovery_count = recovery_count2;
	if (recovery_count < 2)
		recovery_count = 2; 
	if (recovery_count > 17) {
		active_count += recovery_count - 17;
		recovery_count = 17;
	}
	if (active_count > 16)
		active_count = 16; 
	if (cmd640_chip_version > 1)
		recovery_count -= 1;  
	if (recovery_count > 16)
		recovery_count = 16; 

	setup_counts[index]    = setup_count;
	active_counts[index]   = active_count;
	recovery_counts[index] = recovery_count;

	
	program_drive_counts(drive, index);
}
static void __init cmd640_init_dev(ide_drive_t *drive)
{
	unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1);

#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
	setup_counts[i]    =  4;	
	active_counts[i]   = 16;	
	recovery_counts[i] = 16;	
	program_drive_counts(drive, i);
	set_prefetch_mode(drive, i, 0);
	printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch cleared\n", i);
#else
	check_prefetch(drive, i);
	printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n",
		i, (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) ? "off" : "on");
#endif 
}
static void cmd640_init_dev(ide_drive_t *drive)
{
	unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1);

#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
	/*
	 * Reset timing to the slowest speed and turn off prefetch.
	 * This way, the drive identify code has a better chance.
	 */
	setup_counts[i]    =  4;	/* max possible */
	active_counts[i]   = 16;	/* max possible */
	recovery_counts[i] = 16;	/* max possible */
	program_drive_counts(drive, i);
	set_prefetch_mode(drive, i, 0);
	printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch cleared\n", i);
#else
	/*
	 * Set the drive unmask flags to match the prefetch setting.
	 */
	check_prefetch(drive, i);
	printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n",
		i, (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) ? "off" : "on");
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
}
/*
 * Set a specific pio_mode for a drive
 */
static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
			    u8 pio_mode, unsigned int cycle_time)
{
	struct ide_timing *t;
	int setup_time, active_time, recovery_time, clock_time;
	u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
	int bus_speed;

	if (cmd640_vlb)
		bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
	else
		bus_speed = ide_pci_clk ? ide_pci_clk : 33;

	if (pio_mode > 5)
		pio_mode = 5;

	t = ide_timing_find_mode(XFER_PIO_0 + pio_mode);
	setup_time  = t->setup;
	active_time = t->active;

	recovery_time = cycle_time - (setup_time + active_time);
	clock_time = 1000 / bus_speed;
	cycle_count = DIV_ROUND_UP(cycle_time, clock_time);

	setup_count = DIV_ROUND_UP(setup_time, clock_time);

	active_count = DIV_ROUND_UP(active_time, clock_time);
	if (active_count < 2)
		active_count = 2; /* minimum allowed by cmd640 */

	recovery_count = DIV_ROUND_UP(recovery_time, clock_time);
	recovery_count2 = cycle_count - (setup_count + active_count);
	if (recovery_count2 > recovery_count)
		recovery_count = recovery_count2;
	if (recovery_count < 2)
		recovery_count = 2; /* minimum allowed by cmd640 */
	if (recovery_count > 17) {
		active_count += recovery_count - 17;
		recovery_count = 17;
	}
	if (active_count > 16)
		active_count = 16; /* maximum allowed by cmd640 */
	if (cmd640_chip_version > 1)
		recovery_count -= 1;  /* cmd640b uses (count + 1)*/
	if (recovery_count > 16)
		recovery_count = 16; /* maximum allowed by cmd640 */

	setup_counts[index]    = setup_count;
	active_counts[index]   = active_count;
	recovery_counts[index] = recovery_count;

	/*
	 * In a perfect world, we might set the drive pio mode here
	 * (using WIN_SETFEATURE) before continuing.
	 *
	 * But we do not, because:
	 *	1) this is the wrong place to do it (proper is do_special() in ide.c)
	 * 	2) in practice this is rarely, if ever, necessary
	 */
	program_drive_counts(drive, index);
}
Beispiel #5
0
static void cmd64x_tuneproc (ide_drive_t *drive, u8 mode_wanted)
{
    int setup_time, active_time, recovery_time;
    int clock_time, pio_mode, cycle_time;
    u8 recovery_count2, cycle_count;
    int setup_count, active_count, recovery_count;
    int bus_speed = system_bus_clock();
    /*byte b;*/
    ide_pio_data_t  d;

    switch (mode_wanted) {
    case 8: /* set prefetch off */
    case 9: /* set prefetch on */
        mode_wanted &= 1;
        /*set_prefetch_mode(index, mode_wanted);*/
        cmdprintk("%s: %sabled cmd640 prefetch\n",
                  drive->name, mode_wanted ? "en" : "dis");
        return;
    }

    mode_wanted = ide_get_best_pio_mode (drive, mode_wanted, 5, &d);
    pio_mode = d.pio_mode;
    cycle_time = d.cycle_time;

    /*
     * I copied all this complicated stuff from cmd640.c and made a few
     * minor changes.  For now I am just going to pray that it is correct.
     */
    if (pio_mode > 5)
        pio_mode = 5;
    setup_time  = ide_pio_timings[pio_mode].setup_time;
    active_time = ide_pio_timings[pio_mode].active_time;
    recovery_time = cycle_time - (setup_time + active_time);
    clock_time = 1000 / bus_speed;
    cycle_count = (cycle_time + clock_time - 1) / clock_time;

    setup_count = (setup_time + clock_time - 1) / clock_time;

    active_count = (active_time + clock_time - 1) / clock_time;

    recovery_count = (recovery_time + clock_time - 1) / clock_time;
    recovery_count2 = cycle_count - (setup_count + active_count);
    if (recovery_count2 > recovery_count)
        recovery_count = recovery_count2;
    if (recovery_count > 16) {
        active_count += recovery_count - 16;
        recovery_count = 16;
    }
    if (active_count > 16)
        active_count = 16; /* maximum allowed by cmd646 */

    /*
     * In a perfect world, we might set the drive pio mode here
     * (using WIN_SETFEATURE) before continuing.
     *
     * But we do not, because:
     *	1) this is the wrong place to do it
     *		(proper is do_special() in ide.c)
     * 	2) in practice this is rarely, if ever, necessary
     */
    program_drive_counts (drive, setup_count, active_count, recovery_count);

    cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns)%s, "
              "clocks=%d/%d/%d\n",
              drive->name, pio_mode, mode_wanted, cycle_time,
              d.overridden ? " (overriding vendor mode)" : "",
              setup_count, active_count, recovery_count);
}