aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-10-16 16:29:52 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-10-16 16:29:52 -0400
commitc77a89cd98d99819f23a4a08e5e17ee1f13f6e4d (patch)
tree7b79c1189547cde4adc5457745a9034690e9245b /drivers
parenta29ec3b2192247f93b10940119079196cf1dfc5c (diff)
sis5513: DMA setup fixes
* Add sis_ata133_get_base() helper function for obtaining the address of the drive control registers on chipset_family == ATA_133 chipsets. * Add three helper functions for programming PIO/MWDMA timings: - sis_ata16_program_timings() (for ATA_16/33/66/100a chipset families) - sis_ata100_program_timings() (for ATA_100/133a chipset families) - sis_ata133_program_timings() (for ATA_133 chipset family) MWDMA timings are taken from datasheets and they match ATA spec. * Add generic helper function sis_program_timings() and use it in ->set_pio_mode and ->set_dma_mode methods (previously the driver depended on BIOS to program the correct MWDMA timings). * Remove redundant !chipset_family check from init_hwif_sis5513() (init_chipset_sis5513() guarantees that we will never get here if chipset_family cannot be determined). * SWDMA seems to be unsupported by SiS chipsets (no info about SWDMA in datasheets and for SWDMA0 mode timing requirements are impossible to fulfill) so remove ->swdma_mask from init_hwif_sis5513() and handling of SWDMA modes from sis_set_dma_mode(). * Enable DMA support for chipset_family == ATA_16. * Bump driver version. Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ide/pci/sis5513.c214
1 files changed, 106 insertions, 108 deletions
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index b375ee53d66d..db8d96bd5a64 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/ide/pci/sis5513.c Version 0.27 Jul 14, 2007 2 * linux/drivers/ide/pci/sis5513.c Version 0.28 Aug 1, 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
@@ -433,6 +433,95 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
433/* 433/*
434 * Configuration functions 434 * Configuration functions
435 */ 435 */
436
437static u8 sis_ata133_get_base(ide_drive_t *drive)
438{
439 struct pci_dev *dev = drive->hwif->pci_dev;
440 u32 reg54 = 0;
441
442 pci_read_config_dword(dev, 0x54, &reg54);
443
444 return ((reg54 & 0x40000000) ? 0x70 : 0x40) + drive->dn * 4;
445}
446
447static void sis_ata16_program_timings(ide_drive_t *drive, const u8 mode)
448{
449 struct pci_dev *dev = drive->hwif->pci_dev;
450 u16 t1 = 0;
451 u8 drive_pci = 0x40 + drive->dn * 2;
452
453 const u16 pio_timings[] = { 0x000, 0x607, 0x404, 0x303, 0x301 };
454 const u16 mwdma_timings[] = { 0x008, 0x302, 0x301 };
455
456 pci_read_config_word(dev, drive_pci, &t1);
457
458 /* clear active/recovery timings */
459 t1 &= ~0x070f;
460 if (mode >= XFER_MW_DMA_0) {
461 if (chipset_family > ATA_16)
462 t1 &= ~0x8000; /* disable UDMA */
463 t1 |= mwdma_timings[mode - XFER_MW_DMA_0];
464 } else
465 t1 |= pio_timings[mode - XFER_PIO_0];
466
467 pci_write_config_word(dev, drive_pci, t1);
468}
469
470static void sis_ata100_program_timings(ide_drive_t *drive, const u8 mode)
471{
472 struct pci_dev *dev = drive->hwif->pci_dev;
473 u8 t1, drive_pci = 0x40 + drive->dn * 2;
474
475 /* timing bits: 7:4 active 3:0 recovery */
476 const u8 pio_timings[] = { 0x00, 0x67, 0x44, 0x33, 0x31 };
477 const u8 mwdma_timings[] = { 0x08, 0x32, 0x31 };
478
479 if (mode >= XFER_MW_DMA_0) {
480 u8 t2 = 0;
481
482 pci_read_config_byte(dev, drive_pci, &t2);
483 t2 &= ~0x80; /* disable UDMA */
484 pci_write_config_byte(dev, drive_pci, t2);
485
486 t1 = mwdma_timings[mode - XFER_MW_DMA_0];
487 } else
488 t1 = pio_timings[mode - XFER_PIO_0];
489
490 pci_write_config_byte(dev, drive_pci + 1, t1);
491}
492
493static void sis_ata133_program_timings(ide_drive_t *drive, const u8 mode)
494{
495 struct pci_dev *dev = drive->hwif->pci_dev;
496 u32 t1 = 0;
497 u8 drive_pci = sis_ata133_get_base(drive), clk, idx;
498
499 pci_read_config_dword(dev, drive_pci, &t1);
500
501 t1 &= 0xc0c00fff;
502 clk = (t1 & 0x08) ? ATA_133 : ATA_100;
503 if (mode >= XFER_MW_DMA_0) {
504 t1 &= ~0x04; /* disable UDMA */
505 idx = mode - XFER_MW_DMA_0 + 5;
506 }
507 idx = mode - XFER_PIO_0;
508 t1 |= ini_time_value[clk][idx] << 12;
509 t1 |= act_time_value[clk][idx] << 16;
510 t1 |= rco_time_value[clk][idx] << 24;
511
512 pci_write_config_dword(dev, drive_pci, t1);
513}
514
515static void sis_program_timings(ide_drive_t *drive, const u8 mode)
516{
517 if (chipset_family < ATA_100) /* ATA_16/33/66/100a */
518 sis_ata16_program_timings(drive, mode);
519 else if (chipset_family < ATA_133) /* ATA_100/133a */
520 sis_ata100_program_timings(drive, mode);
521 else /* ATA_133 */
522 sis_ata133_program_timings(drive, mode);
523}
524
436/* Enables per-drive prefetch and postwrite */ 525/* Enables per-drive prefetch and postwrite */
437static void config_drive_art_rwp (ide_drive_t *drive) 526static void config_drive_art_rwp (ide_drive_t *drive)
438{ 527{
@@ -450,105 +539,16 @@ static void config_drive_art_rwp (ide_drive_t *drive)
450 pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch); 539 pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
451} 540}
452 541
453/* Set per-drive active and recovery time */
454static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio) 542static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
455{ 543{
456 ide_hwif_t *hwif = HWIF(drive);
457 struct pci_dev *dev = hwif->pci_dev;
458
459 u8 drive_pci, test1, test2;
460
461 config_drive_art_rwp(drive); 544 config_drive_art_rwp(drive);
462 545 sis_program_timings(drive, XFER_PIO_0 + pio);
463 /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */
464 drive_pci = 0x40;
465 /* In SiS962 case drives sit at (0x40 or 0x70) + 8*drive->dn) */
466 if (chipset_family >= ATA_133) {
467 u32 reg54h;
468 pci_read_config_dword(dev, 0x54, &reg54h);
469 if (reg54h & 0x40000000) drive_pci = 0x70;
470 drive_pci += ((drive->dn)*0x4);
471 } else {
472 drive_pci += ((drive->dn)*0x2);
473 }
474
475 /* register layout changed with newer ATA100 chips */
476 if (chipset_family < ATA_100) {
477 pci_read_config_byte(dev, drive_pci, &test1);
478 pci_read_config_byte(dev, drive_pci+1, &test2);
479
480 /* Clear active and recovery timings */
481 test1 &= ~0x0F;
482 test2 &= ~0x07;
483
484 switch(pio) {
485 case 4: test1 |= 0x01; test2 |= 0x03; break;
486 case 3: test1 |= 0x03; test2 |= 0x03; break;
487 case 2: test1 |= 0x04; test2 |= 0x04; break;
488 case 1: test1 |= 0x07; test2 |= 0x06; break;
489 case 0: /* PIO0: register setting == X000 */
490 default: break;
491 }
492 pci_write_config_byte(dev, drive_pci, test1);
493 pci_write_config_byte(dev, drive_pci+1, test2);
494 } else if (chipset_family < ATA_133) {
495 switch(pio) { /* active recovery
496 v v */
497 case 4: test1 = 0x30|0x01; break;
498 case 3: test1 = 0x30|0x03; break;
499 case 2: test1 = 0x40|0x04; break;
500 case 1: test1 = 0x60|0x07; break;
501 case 0: test1 = 0x00; break;
502 default: break;
503 }
504 pci_write_config_byte(dev, drive_pci, test1);
505 } else { /* ATA_133 */
506 u32 test3;
507 pci_read_config_dword(dev, drive_pci, &test3);
508 test3 &= 0xc0c00fff;
509 if (test3 & 0x08) {
510 test3 |= ini_time_value[ATA_133][pio] << 12;
511 test3 |= act_time_value[ATA_133][pio] << 16;
512 test3 |= rco_time_value[ATA_133][pio] << 24;
513 } else {
514 test3 |= ini_time_value[ATA_100][pio] << 12;
515 test3 |= act_time_value[ATA_100][pio] << 16;
516 test3 |= rco_time_value[ATA_100][pio] << 24;
517 }
518 pci_write_config_dword(dev, drive_pci, test3);
519 }
520} 546}
521 547
522static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed) 548static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
523{ 549{
524 ide_hwif_t *hwif = HWIF(drive); 550 ide_hwif_t *hwif = HWIF(drive);
525 struct pci_dev *dev = hwif->pci_dev; 551 struct pci_dev *dev = hwif->pci_dev;
526 u32 regdw;
527 u8 drive_pci, reg;
528
529 /* See sis_set_pio_mode() for drive PCI config registers */
530 drive_pci = 0x40;
531 if (chipset_family >= ATA_133) {
532 u32 reg54h;
533 pci_read_config_dword(dev, 0x54, &reg54h);
534 if (reg54h & 0x40000000) drive_pci = 0x70;
535 drive_pci += ((drive->dn)*0x4);
536 pci_read_config_dword(dev, (unsigned long)drive_pci, &regdw);
537 /* Disable UDMA bit for non UDMA modes on UDMA chips */
538 if (speed < XFER_UDMA_0) {
539 regdw &= 0xfffffffb;
540 pci_write_config_dword(dev, (unsigned long)drive_pci, regdw);
541 }
542
543 } else {
544 drive_pci += ((drive->dn)*0x2);
545 pci_read_config_byte(dev, drive_pci+1, &reg);
546 /* Disable UDMA bit for non UDMA modes on UDMA chips */
547 if ((speed < XFER_UDMA_0) && (chipset_family > ATA_16)) {
548 reg &= 0x7F;
549 pci_write_config_byte(dev, drive_pci+1, reg);
550 }
551 }
552 552
553 /* Config chip for mode */ 553 /* Config chip for mode */
554 switch(speed) { 554 switch(speed) {
@@ -560,6 +560,10 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
560 case XFER_UDMA_1: 560 case XFER_UDMA_1:
561 case XFER_UDMA_0: 561 case XFER_UDMA_0:
562 if (chipset_family >= ATA_133) { 562 if (chipset_family >= ATA_133) {
563 u32 regdw = 0;
564 u8 drive_pci = sis_ata133_get_base(drive);
565
566 pci_read_config_dword(dev, drive_pci, &regdw);
563 regdw |= 0x04; 567 regdw |= 0x04;
564 regdw &= 0xfffff00f; 568 regdw &= 0xfffff00f;
565 /* check if ATA133 enable */ 569 /* check if ATA133 enable */
@@ -572,6 +576,9 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
572 } 576 }
573 pci_write_config_dword(dev, (unsigned long)drive_pci, regdw); 577 pci_write_config_dword(dev, (unsigned long)drive_pci, regdw);
574 } else { 578 } else {
579 u8 drive_pci = 0x40 + drive->dn * 2, reg = 0;
580
581 pci_read_config_byte(dev, drive_pci+1, &reg);
575 /* Force the UDMA bit on if we want to use UDMA */ 582 /* Force the UDMA bit on if we want to use UDMA */
576 reg |= 0x80; 583 reg |= 0x80;
577 /* clean reg cycle time bits */ 584 /* clean reg cycle time bits */
@@ -586,9 +593,7 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
586 case XFER_MW_DMA_2: 593 case XFER_MW_DMA_2:
587 case XFER_MW_DMA_1: 594 case XFER_MW_DMA_1:
588 case XFER_MW_DMA_0: 595 case XFER_MW_DMA_0:
589 case XFER_SW_DMA_2: 596 sis_program_timings(drive, speed);
590 case XFER_SW_DMA_1:
591 case XFER_SW_DMA_0:
592 break; 597 break;
593 default: 598 default:
594 BUG(); 599 BUG();
@@ -617,11 +622,9 @@ static int sis5513_config_xfer_rate(ide_drive_t *drive)
617static u8 sis5513_ata133_udma_filter(ide_drive_t *drive) 622static u8 sis5513_ata133_udma_filter(ide_drive_t *drive)
618{ 623{
619 struct pci_dev *dev = drive->hwif->pci_dev; 624 struct pci_dev *dev = drive->hwif->pci_dev;
620 int drive_pci; 625 u32 regdw = 0;
621 u32 reg54 = 0, regdw = 0; 626 u8 drive_pci = sis_ata133_get_base(drive);
622 627
623 pci_read_config_dword(dev, 0x54, &reg54);
624 drive_pci = ((reg54 & 0x40000000) ? 0x70 : 0x40) + drive->dn * 4;
625 pci_read_config_dword(dev, drive_pci, &regdw); 628 pci_read_config_dword(dev, drive_pci, &regdw);
626 629
627 /* if ATA133 disable, we should not set speed above UDMA5 */ 630 /* if ATA133 disable, we should not set speed above UDMA5 */
@@ -848,22 +851,17 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
848 851
849 hwif->ultra_mask = udma_rates[chipset_family]; 852 hwif->ultra_mask = udma_rates[chipset_family];
850 hwif->mwdma_mask = 0x07; 853 hwif->mwdma_mask = 0x07;
851 hwif->swdma_mask = 0x07;
852
853 if (!chipset_family)
854 return;
855 854
856 if (hwif->cbl != ATA_CBL_PATA40_SHORT) 855 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
857 hwif->cbl = ata66_sis5513(hwif); 856 hwif->cbl = ata66_sis5513(hwif);
858 857
859 if (chipset_family > ATA_16) { 858 hwif->ide_dma_check = &sis5513_config_xfer_rate;
860 hwif->ide_dma_check = &sis5513_config_xfer_rate; 859
861 if (!noautodma) 860 if (!noautodma)
862 hwif->autodma = 1; 861 hwif->autodma = 1;
863 } 862
864 hwif->drives[0].autodma = hwif->autodma; 863 hwif->drives[0].autodma = hwif->autodma;
865 hwif->drives[1].autodma = hwif->autodma; 864 hwif->drives[1].autodma = hwif->autodma;
866 return;
867} 865}
868 866
869static ide_pci_device_t sis5513_chipset __devinitdata = { 867static ide_pci_device_t sis5513_chipset __devinitdata = {