|
@@ -1,6 +1,6 @@
|
|
|
/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16
|
|
|
*
|
|
|
- * linux/drivers/ide/pci/cmd64x.c Version 1.41 Feb 3, 2007
|
|
|
+ * linux/drivers/ide/pci/cmd64x.c Version 1.42 Feb 8, 2007
|
|
|
*
|
|
|
* cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
|
|
|
* Note, this driver is not used at all on other systems because
|
|
@@ -189,6 +189,11 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
|
|
|
|
|
|
#endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */
|
|
|
|
|
|
+static u8 quantize_timing(int timing, int quant)
|
|
|
+{
|
|
|
+ return (timing + quant - 1) / quant;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* This routine writes the prepared setup/active/recovery counts
|
|
|
* for a drive into the cmd646 chipset registers to active them.
|
|
@@ -268,47 +273,37 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
|
|
|
*/
|
|
|
static u8 cmd64x_tune_pio (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();
|
|
|
- ide_pio_data_t d;
|
|
|
+ int setup_time, active_time, cycle_time;
|
|
|
+ u8 cycle_count, setup_count, active_count, recovery_count;
|
|
|
+ u8 pio_mode;
|
|
|
+ int clock_time = 1000 / system_bus_clock();
|
|
|
+ ide_pio_data_t pio;
|
|
|
|
|
|
- pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &d);
|
|
|
- cycle_time = d.cycle_time;
|
|
|
+ pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio);
|
|
|
+ cycle_time = pio.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.
|
|
|
- */
|
|
|
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;
|
|
|
+ setup_count = quantize_timing( setup_time, clock_time);
|
|
|
+ cycle_count = quantize_timing( cycle_time, clock_time);
|
|
|
+ active_count = quantize_timing(active_time, 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;
|
|
|
+ recovery_count = cycle_count - active_count;
|
|
|
+ /* program_drive_counts() takes care of zero recovery cycles */
|
|
|
if (recovery_count > 16) {
|
|
|
active_count += recovery_count - 16;
|
|
|
recovery_count = 16;
|
|
|
}
|
|
|
if (active_count > 16)
|
|
|
- active_count = 16; /* maximum allowed by cmd646 */
|
|
|
+ active_count = 16; /* maximum allowed by cmd64x */
|
|
|
|
|
|
program_drive_counts (drive, setup_count, active_count, recovery_count);
|
|
|
|
|
|
cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, "
|
|
|
"clocks=%d/%d/%d\n",
|
|
|
drive->name, mode_wanted, pio_mode, cycle_time,
|
|
|
- d.overridden ? " (overriding vendor mode)" : "",
|
|
|
+ pio.overridden ? " (overriding vendor mode)" : "",
|
|
|
setup_count, active_count, recovery_count);
|
|
|
|
|
|
return pio_mode;
|