aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/pci/cmd640.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/pci/cmd640.c')
-rw-r--r--drivers/ide/pci/cmd640.c89
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/* 114static int cmd640_vlb;
115 * This flag is set in ide.c by the parameter: ide0=cmd640_vlb
116 */
117int 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 */
467static 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