aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/pci/sis5513.c85
1 files changed, 36 insertions, 49 deletions
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 2bde1b92784a..bb6cc4aedd63 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -1,9 +1,11 @@
1/* 1/*
2 * linux/drivers/ide/pci/sis5513.c Version 0.16ac+vp Jun 18, 2003 2 * linux/drivers/ide/pci/sis5513.c Version 0.20 Mar 4, 2007
3 * 3 *
4 * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> 4 * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
5 * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer 5 * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
6 * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz> 6 * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz>
7 * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
8 *
7 * May be copied or modified under the terms of the GNU General Public License 9 * May be copied or modified under the terms of the GNU General Public License
8 * 10 *
9 * 11 *
@@ -448,36 +450,15 @@ static void config_drive_art_rwp (ide_drive_t *drive)
448 pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch); 450 pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
449} 451}
450 452
451
452/* Set per-drive active and recovery time */ 453/* Set per-drive active and recovery time */
453static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) 454static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
454{ 455{
455 ide_hwif_t *hwif = HWIF(drive); 456 ide_hwif_t *hwif = HWIF(drive);
456 struct pci_dev *dev = hwif->pci_dev; 457 struct pci_dev *dev = hwif->pci_dev;
457 458
458 u8 timing, drive_pci, test1, test2; 459 u8 drive_pci, test1, test2;
459
460 u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90};
461 u16 xfer_pio = drive->id->eide_pio_modes;
462 460
463 config_drive_art_rwp(drive); 461 config_drive_art_rwp(drive);
464 pio = ide_get_best_pio_mode(drive, 255, pio, NULL);
465
466 if (xfer_pio> 4)
467 xfer_pio = 0;
468
469 if (drive->id->eide_pio_iordy > 0) {
470 for (xfer_pio = 5;
471 (xfer_pio > 0) &&
472 (drive->id->eide_pio_iordy > eide_pio_timing[xfer_pio]);
473 xfer_pio--);
474 } else {
475 xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
476 (drive->id->eide_pio_modes & 2) ? 0x04 :
477 (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio;
478 }
479
480 timing = (xfer_pio >= pio) ? xfer_pio : pio;
481 462
482 /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */ 463 /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */
483 drive_pci = 0x40; 464 drive_pci = 0x40;
@@ -500,17 +481,18 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
500 test1 &= ~0x0F; 481 test1 &= ~0x0F;
501 test2 &= ~0x07; 482 test2 &= ~0x07;
502 483
503 switch(timing) { 484 switch(pio) {
504 case 4: test1 |= 0x01; test2 |= 0x03; break; 485 case 4: test1 |= 0x01; test2 |= 0x03; break;
505 case 3: test1 |= 0x03; test2 |= 0x03; break; 486 case 3: test1 |= 0x03; test2 |= 0x03; break;
506 case 2: test1 |= 0x04; test2 |= 0x04; break; 487 case 2: test1 |= 0x04; test2 |= 0x04; break;
507 case 1: test1 |= 0x07; test2 |= 0x06; break; 488 case 1: test1 |= 0x07; test2 |= 0x06; break;
489 case 0: /* PIO0: register setting == X000 */
508 default: break; 490 default: break;
509 } 491 }
510 pci_write_config_byte(dev, drive_pci, test1); 492 pci_write_config_byte(dev, drive_pci, test1);
511 pci_write_config_byte(dev, drive_pci+1, test2); 493 pci_write_config_byte(dev, drive_pci+1, test2);
512 } else if (chipset_family < ATA_133) { 494 } else if (chipset_family < ATA_133) {
513 switch(timing) { /* active recovery 495 switch(pio) { /* active recovery
514 v v */ 496 v v */
515 case 4: test1 = 0x30|0x01; break; 497 case 4: test1 = 0x30|0x01; break;
516 case 3: test1 = 0x30|0x03; break; 498 case 3: test1 = 0x30|0x03; break;
@@ -525,24 +507,28 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
525 pci_read_config_dword(dev, drive_pci, &test3); 507 pci_read_config_dword(dev, drive_pci, &test3);
526 test3 &= 0xc0c00fff; 508 test3 &= 0xc0c00fff;
527 if (test3 & 0x08) { 509 if (test3 & 0x08) {
528 test3 |= (unsigned long)ini_time_value[ATA_133][timing] << 12; 510 test3 |= ini_time_value[ATA_133][pio] << 12;
529 test3 |= (unsigned long)act_time_value[ATA_133][timing] << 16; 511 test3 |= act_time_value[ATA_133][pio] << 16;
530 test3 |= (unsigned long)rco_time_value[ATA_133][timing] << 24; 512 test3 |= rco_time_value[ATA_133][pio] << 24;
531 } else { 513 } else {
532 test3 |= (unsigned long)ini_time_value[ATA_100][timing] << 12; 514 test3 |= ini_time_value[ATA_100][pio] << 12;
533 test3 |= (unsigned long)act_time_value[ATA_100][timing] << 16; 515 test3 |= act_time_value[ATA_100][pio] << 16;
534 test3 |= (unsigned long)rco_time_value[ATA_100][timing] << 24; 516 test3 |= rco_time_value[ATA_100][pio] << 24;
535 } 517 }
536 pci_write_config_dword(dev, drive_pci, test3); 518 pci_write_config_dword(dev, drive_pci, test3);
537 } 519 }
538} 520}
539 521
540static int config_chipset_for_pio (ide_drive_t *drive, u8 pio) 522static int sis5513_tune_drive(ide_drive_t *drive, u8 pio)
541{ 523{
542 if (pio == 255) 524 pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
543 pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
544 config_art_rwp_pio(drive, pio); 525 config_art_rwp_pio(drive, pio);
545 return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4)); 526 return ide_config_drive_speed(drive, XFER_PIO_0 + pio);
527}
528
529static void sis5513_tuneproc(ide_drive_t *drive, u8 pio)
530{
531 (void)sis5513_tune_drive(drive, pio);
546} 532}
547 533
548static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) 534static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
@@ -622,25 +608,26 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
622 case XFER_SW_DMA_1: 608 case XFER_SW_DMA_1:
623 case XFER_SW_DMA_0: 609 case XFER_SW_DMA_0:
624 break; 610 break;
625 case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4)); 611 case XFER_PIO_4:
626 case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3)); 612 case XFER_PIO_3:
627 case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2)); 613 case XFER_PIO_2:
628 case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1)); 614 case XFER_PIO_1:
629 case XFER_PIO_0: 615 case XFER_PIO_0:
630 default: return((int) config_chipset_for_pio(drive, 0)); 616 return sis5513_tune_drive(drive, speed - XFER_PIO_0);
617 default:
618 BUG();
619 break;
631 } 620 }
632 621
633 return ((int) ide_config_drive_speed(drive, speed)); 622 return ide_config_drive_speed(drive, speed);
634}
635
636static void sis5513_tune_drive (ide_drive_t *drive, u8 pio)
637{
638 (void) config_chipset_for_pio(drive, pio);
639} 623}
640 624
641static int sis5513_config_xfer_rate(ide_drive_t *drive) 625static int sis5513_config_xfer_rate(ide_drive_t *drive)
642{ 626{
643 config_art_rwp_pio(drive, 5); 627 /*
628 * TODO: always set PIO mode and remove this
629 */
630 sis5513_tuneproc(drive, 255);
644 631
645 drive->init_speed = 0; 632 drive->init_speed = 0;
646 633
@@ -648,7 +635,7 @@ static int sis5513_config_xfer_rate(ide_drive_t *drive)
648 return 0; 635 return 0;
649 636
650 if (ide_use_fast_pio(drive)) 637 if (ide_use_fast_pio(drive))
651 sis5513_tune_drive(drive, 5); 638 sis5513_tuneproc(drive, 255);
652 639
653 return -1; 640 return -1;
654} 641}
@@ -836,7 +823,7 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
836 if (!hwif->irq) 823 if (!hwif->irq)
837 hwif->irq = hwif->channel ? 15 : 14; 824 hwif->irq = hwif->channel ? 15 : 14;
838 825
839 hwif->tuneproc = &sis5513_tune_drive; 826 hwif->tuneproc = &sis5513_tuneproc;
840 hwif->speedproc = &sis5513_tune_chipset; 827 hwif->speedproc = &sis5513_tune_chipset;
841 828
842 if (!(hwif->dma_base)) { 829 if (!(hwif->dma_base)) {