diff options
Diffstat (limited to 'drivers/ide/pci/cmd640.c')
-rw-r--r-- | drivers/ide/pci/cmd640.c | 89 |
1 files changed, 25 insertions, 64 deletions
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index 25c2f1bd175..aaf38109eae 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c | |||
@@ -111,10 +111,7 @@ | |||
111 | 111 | ||
112 | #define DRV_NAME "cmd640" | 112 | #define DRV_NAME "cmd640" |
113 | 113 | ||
114 | /* | 114 | static int cmd640_vlb; |
115 | * This flag is set in ide.c by the parameter: ide0=cmd640_vlb | ||
116 | */ | ||
117 | int cmd640_vlb; | ||
118 | 115 | ||
119 | /* | 116 | /* |
120 | * CMD640 specific registers definition. | 117 | * CMD640 specific registers definition. |
@@ -350,12 +347,12 @@ static int __init secondary_port_responding(void) | |||
350 | 347 | ||
351 | spin_lock_irqsave(&cmd640_lock, flags); | 348 | spin_lock_irqsave(&cmd640_lock, flags); |
352 | 349 | ||
353 | outb_p(0x0a, 0x170 + IDE_SELECT_OFFSET); /* select drive0 */ | 350 | outb_p(0x0a, 0x176); /* select drive0 */ |
354 | udelay(100); | 351 | udelay(100); |
355 | if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x0a) { | 352 | if ((inb_p(0x176) & 0x1f) != 0x0a) { |
356 | outb_p(0x1a, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */ | 353 | outb_p(0x1a, 0x176); /* select drive1 */ |
357 | udelay(100); | 354 | udelay(100); |
358 | if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x1a) { | 355 | if ((inb_p(0x176) & 0x1f) != 0x1a) { |
359 | spin_unlock_irqrestore(&cmd640_lock, flags); | 356 | spin_unlock_irqrestore(&cmd640_lock, flags); |
360 | return 0; /* nothing responded */ | 357 | return 0; /* nothing responded */ |
361 | } | 358 | } |
@@ -383,6 +380,7 @@ static void cmd640_dump_regs(void) | |||
383 | } | 380 | } |
384 | #endif | 381 | #endif |
385 | 382 | ||
383 | #ifndef CONFIG_BLK_DEV_CMD640_ENHANCED | ||
386 | /* | 384 | /* |
387 | * Check whether prefetch is on for a drive, | 385 | * Check whether prefetch is on for a drive, |
388 | * and initialize the unmask flags for safe operation. | 386 | * and initialize the unmask flags for safe operation. |
@@ -403,9 +401,7 @@ static void __init check_prefetch(ide_drive_t *drive, unsigned int index) | |||
403 | drive->no_io_32bit = 0; | 401 | drive->no_io_32bit = 0; |
404 | } | 402 | } |
405 | } | 403 | } |
406 | 404 | #else | |
407 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | ||
408 | |||
409 | /* | 405 | /* |
410 | * Sets prefetch mode for a drive. | 406 | * Sets prefetch mode for a drive. |
411 | */ | 407 | */ |
@@ -462,34 +458,6 @@ static inline u8 pack_nibbles(u8 upper, u8 lower) | |||
462 | } | 458 | } |
463 | 459 | ||
464 | /* | 460 | /* |
465 | * This routine retrieves the initial drive timings from the chipset. | ||
466 | */ | ||
467 | static void __init retrieve_drive_counts(unsigned int index) | ||
468 | { | ||
469 | u8 b; | ||
470 | |||
471 | /* | ||
472 | * Get the internal setup timing, and convert to clock count | ||
473 | */ | ||
474 | b = get_cmd640_reg(arttim_regs[index]) & ~0x3f; | ||
475 | switch (b) { | ||
476 | case 0x00: b = 4; break; | ||
477 | case 0x80: b = 3; break; | ||
478 | case 0x40: b = 2; break; | ||
479 | default: b = 5; break; | ||
480 | } | ||
481 | setup_counts[index] = b; | ||
482 | |||
483 | /* | ||
484 | * Get the active/recovery counts | ||
485 | */ | ||
486 | b = get_cmd640_reg(drwtim_regs[index]); | ||
487 | active_counts[index] = (b >> 4) ? (b >> 4) : 0x10; | ||
488 | recovery_counts[index] = (b & 0x0f) ? (b & 0x0f) : 0x10; | ||
489 | } | ||
490 | |||
491 | |||
492 | /* | ||
493 | * This routine writes the prepared setup/active/recovery counts | 461 | * This routine writes the prepared setup/active/recovery counts |
494 | * for a drive into the cmd640 chipset registers to active them. | 462 | * for a drive into the cmd640 chipset registers to active them. |
495 | */ | 463 | */ |
@@ -555,7 +523,14 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, | |||
555 | { | 523 | { |
556 | int setup_time, active_time, recovery_time, clock_time; | 524 | int setup_time, active_time, recovery_time, clock_time; |
557 | u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; | 525 | u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; |
558 | int bus_speed = system_bus_clock(); | 526 | int bus_speed; |
527 | |||
528 | if (cmd640_vlb && ide_vlb_clk) | ||
529 | bus_speed = ide_vlb_clk; | ||
530 | else if (!cmd640_vlb && ide_pci_clk) | ||
531 | bus_speed = ide_pci_clk; | ||
532 | else | ||
533 | bus_speed = system_bus_clock(); | ||
559 | 534 | ||
560 | if (pio_mode > 5) | 535 | if (pio_mode > 5) |
561 | pio_mode = 5; | 536 | pio_mode = 5; |
@@ -679,7 +654,6 @@ static const struct ide_port_info cmd640_port_info __initdata = { | |||
679 | .chipset = ide_cmd640, | 654 | .chipset = ide_cmd640, |
680 | .host_flags = IDE_HFLAG_SERIALIZE | | 655 | .host_flags = IDE_HFLAG_SERIALIZE | |
681 | IDE_HFLAG_NO_DMA | | 656 | IDE_HFLAG_NO_DMA | |
682 | IDE_HFLAG_NO_AUTOTUNE | | ||
683 | IDE_HFLAG_ABUSE_PREFETCH | | 657 | IDE_HFLAG_ABUSE_PREFETCH | |
684 | IDE_HFLAG_ABUSE_FAST_DEVSEL, | 658 | IDE_HFLAG_ABUSE_FAST_DEVSEL, |
685 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | 659 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED |
@@ -862,29 +836,16 @@ static int __init cmd640x_init(void) | |||
862 | } | 836 | } |
863 | 837 | ||
864 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | 838 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED |
865 | if (drive->autotune || ((index > 1) && second_port_toggled)) { | 839 | /* |
866 | /* | 840 | * Reset timing to the slowest speed and turn off prefetch. |
867 | * Reset timing to the slowest speed and turn off | 841 | * This way, the drive identify code has a better chance. |
868 | * prefetch. This way, the drive identify code has | 842 | */ |
869 | * a better chance. | 843 | setup_counts [index] = 4; /* max possible */ |
870 | */ | 844 | active_counts [index] = 16; /* max possible */ |
871 | setup_counts [index] = 4; /* max possible */ | 845 | recovery_counts [index] = 16; /* max possible */ |
872 | active_counts [index] = 16; /* max possible */ | 846 | program_drive_counts(drive, index); |
873 | recovery_counts [index] = 16; /* max possible */ | 847 | set_prefetch_mode(drive, index, 0); |
874 | program_drive_counts(drive, index); | 848 | printk("cmd640: drive%d timings/prefetch cleared\n", index); |
875 | set_prefetch_mode(drive, index, 0); | ||
876 | printk("cmd640: drive%d timings/prefetch cleared\n", index); | ||
877 | } else { | ||
878 | /* | ||
879 | * Record timings/prefetch without changing them. | ||
880 | * This preserves any prior BIOS setup. | ||
881 | */ | ||
882 | retrieve_drive_counts (index); | ||
883 | check_prefetch(drive, index); | ||
884 | printk("cmd640: drive%d timings/prefetch(%s) preserved", | ||
885 | index, drive->no_io_32bit ? "off" : "on"); | ||
886 | display_clocks(index); | ||
887 | } | ||
888 | #else | 849 | #else |
889 | /* | 850 | /* |
890 | * Set the drive unmask flags to match the prefetch setting | 851 | * Set the drive unmask flags to match the prefetch setting |