diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2008-01-25 16:17:05 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-25 16:17:05 -0500 |
commit | 866664d79f6a920af07e6503f64366f4c5b2d41f (patch) | |
tree | 74a6b06d79be8f3b0bb195657c37b386a21ac9cf /drivers/ide/pci/hpt366.c | |
parent | a488f34e0dc7180f35fe48a60596fc82fe69d3ef (diff) |
hpt366: merge set_dma_mode() methods
Group the array of pointers to the timing tables with the timing register masks
which allows us to merge HPT36x/HPT37x set_dma_mode() methods into one.
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci/hpt366.c')
-rw-r--r-- | drivers/ide/pci/hpt366.c | 129 |
1 files changed, 58 insertions, 71 deletions
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index faf77fd2e4ef..df14d692743c 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/hpt366.c Version 1.24 Dec 8, 2007 | 2 | * linux/drivers/ide/pci/hpt366.c Version 1.30 Dec 12, 2007 |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
@@ -88,7 +88,7 @@ | |||
88 | * - rename all the register related variables consistently | 88 | * - rename all the register related variables consistently |
89 | * - move all the interrupt twiddling code from the speedproc handlers into | 89 | * - move all the interrupt twiddling code from the speedproc handlers into |
90 | * init_hwif_hpt366(), also grouping all the DMA related code together there | 90 | * init_hwif_hpt366(), also grouping all the DMA related code together there |
91 | * - merge two HPT37x speedproc handlers, fix the PIO timing register mask and | 91 | * - merge HPT36x/HPT37x speedproc handlers, fix PIO timing register mask and |
92 | * separate the UltraDMA and MWDMA masks there to avoid changing PIO timings | 92 | * separate the UltraDMA and MWDMA masks there to avoid changing PIO timings |
93 | * when setting an UltraDMA mode | 93 | * when setting an UltraDMA mode |
94 | * - fix hpt3xx_tune_drive() to set the PIO mode requested, not always select | 94 | * - fix hpt3xx_tune_drive() to set the PIO mode requested, not always select |
@@ -458,6 +458,13 @@ enum ata_clock { | |||
458 | NUM_ATA_CLOCKS | 458 | NUM_ATA_CLOCKS |
459 | }; | 459 | }; |
460 | 460 | ||
461 | struct hpt_timings { | ||
462 | u32 pio_mask; | ||
463 | u32 dma_mask; | ||
464 | u32 ultra_mask; | ||
465 | u32 *clock_table[NUM_ATA_CLOCKS]; | ||
466 | }; | ||
467 | |||
461 | /* | 468 | /* |
462 | * Hold all the HighPoint chip information in one place. | 469 | * Hold all the HighPoint chip information in one place. |
463 | */ | 470 | */ |
@@ -468,7 +475,8 @@ struct hpt_info { | |||
468 | u8 udma_mask; /* Allowed UltraDMA modes mask. */ | 475 | u8 udma_mask; /* Allowed UltraDMA modes mask. */ |
469 | u8 dpll_clk; /* DPLL clock in MHz */ | 476 | u8 dpll_clk; /* DPLL clock in MHz */ |
470 | u8 pci_clk; /* PCI clock in MHz */ | 477 | u8 pci_clk; /* PCI clock in MHz */ |
471 | u32 **settings; /* Chipset settings table */ | 478 | struct hpt_timings *timings; /* Chipset timing data */ |
479 | u8 clock; /* ATA clock selected */ | ||
472 | }; | 480 | }; |
473 | 481 | ||
474 | /* Supported HighPoint chips */ | 482 | /* Supported HighPoint chips */ |
@@ -486,20 +494,30 @@ enum { | |||
486 | HPT371N | 494 | HPT371N |
487 | }; | 495 | }; |
488 | 496 | ||
489 | static u32 *hpt36x_settings[NUM_ATA_CLOCKS] = { | 497 | static struct hpt_timings hpt36x_timings = { |
490 | twenty_five_base_hpt36x, | 498 | .pio_mask = 0xc1f8ffff, |
491 | thirty_three_base_hpt36x, | 499 | .dma_mask = 0x303800ff, |
492 | forty_base_hpt36x, | 500 | .ultra_mask = 0x30070000, |
493 | NULL, | 501 | .clock_table = { |
494 | NULL | 502 | [ATA_CLOCK_25MHZ] = twenty_five_base_hpt36x, |
503 | [ATA_CLOCK_33MHZ] = thirty_three_base_hpt36x, | ||
504 | [ATA_CLOCK_40MHZ] = forty_base_hpt36x, | ||
505 | [ATA_CLOCK_50MHZ] = NULL, | ||
506 | [ATA_CLOCK_66MHZ] = NULL | ||
507 | } | ||
495 | }; | 508 | }; |
496 | 509 | ||
497 | static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = { | 510 | static struct hpt_timings hpt37x_timings = { |
498 | NULL, | 511 | .pio_mask = 0xcfc3ffff, |
499 | thirty_three_base_hpt37x, | 512 | .dma_mask = 0x31c001ff, |
500 | NULL, | 513 | .ultra_mask = 0x303c0000, |
501 | fifty_base_hpt37x, | 514 | .clock_table = { |
502 | sixty_six_base_hpt37x | 515 | [ATA_CLOCK_25MHZ] = NULL, |
516 | [ATA_CLOCK_33MHZ] = thirty_three_base_hpt37x, | ||
517 | [ATA_CLOCK_40MHZ] = NULL, | ||
518 | [ATA_CLOCK_50MHZ] = fifty_base_hpt37x, | ||
519 | [ATA_CLOCK_66MHZ] = sixty_six_base_hpt37x | ||
520 | } | ||
503 | }; | 521 | }; |
504 | 522 | ||
505 | static const struct hpt_info hpt36x __devinitdata = { | 523 | static const struct hpt_info hpt36x __devinitdata = { |
@@ -507,7 +525,7 @@ static const struct hpt_info hpt36x __devinitdata = { | |||
507 | .chip_type = HPT36x, | 525 | .chip_type = HPT36x, |
508 | .udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2, | 526 | .udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2, |
509 | .dpll_clk = 0, /* no DPLL */ | 527 | .dpll_clk = 0, /* no DPLL */ |
510 | .settings = hpt36x_settings | 528 | .timings = &hpt36x_timings |
511 | }; | 529 | }; |
512 | 530 | ||
513 | static const struct hpt_info hpt370 __devinitdata = { | 531 | static const struct hpt_info hpt370 __devinitdata = { |
@@ -515,7 +533,7 @@ static const struct hpt_info hpt370 __devinitdata = { | |||
515 | .chip_type = HPT370, | 533 | .chip_type = HPT370, |
516 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, | 534 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, |
517 | .dpll_clk = 48, | 535 | .dpll_clk = 48, |
518 | .settings = hpt37x_settings | 536 | .timings = &hpt37x_timings |
519 | }; | 537 | }; |
520 | 538 | ||
521 | static const struct hpt_info hpt370a __devinitdata = { | 539 | static const struct hpt_info hpt370a __devinitdata = { |
@@ -523,7 +541,7 @@ static const struct hpt_info hpt370a __devinitdata = { | |||
523 | .chip_type = HPT370A, | 541 | .chip_type = HPT370A, |
524 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, | 542 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, |
525 | .dpll_clk = 48, | 543 | .dpll_clk = 48, |
526 | .settings = hpt37x_settings | 544 | .timings = &hpt37x_timings |
527 | }; | 545 | }; |
528 | 546 | ||
529 | static const struct hpt_info hpt374 __devinitdata = { | 547 | static const struct hpt_info hpt374 __devinitdata = { |
@@ -531,7 +549,7 @@ static const struct hpt_info hpt374 __devinitdata = { | |||
531 | .chip_type = HPT374, | 549 | .chip_type = HPT374, |
532 | .udma_mask = ATA_UDMA5, | 550 | .udma_mask = ATA_UDMA5, |
533 | .dpll_clk = 48, | 551 | .dpll_clk = 48, |
534 | .settings = hpt37x_settings | 552 | .timings = &hpt37x_timings |
535 | }; | 553 | }; |
536 | 554 | ||
537 | static const struct hpt_info hpt372 __devinitdata = { | 555 | static const struct hpt_info hpt372 __devinitdata = { |
@@ -539,7 +557,7 @@ static const struct hpt_info hpt372 __devinitdata = { | |||
539 | .chip_type = HPT372, | 557 | .chip_type = HPT372, |
540 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 558 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
541 | .dpll_clk = 55, | 559 | .dpll_clk = 55, |
542 | .settings = hpt37x_settings | 560 | .timings = &hpt37x_timings |
543 | }; | 561 | }; |
544 | 562 | ||
545 | static const struct hpt_info hpt372a __devinitdata = { | 563 | static const struct hpt_info hpt372a __devinitdata = { |
@@ -547,7 +565,7 @@ static const struct hpt_info hpt372a __devinitdata = { | |||
547 | .chip_type = HPT372A, | 565 | .chip_type = HPT372A, |
548 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 566 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
549 | .dpll_clk = 66, | 567 | .dpll_clk = 66, |
550 | .settings = hpt37x_settings | 568 | .timings = &hpt37x_timings |
551 | }; | 569 | }; |
552 | 570 | ||
553 | static const struct hpt_info hpt302 __devinitdata = { | 571 | static const struct hpt_info hpt302 __devinitdata = { |
@@ -555,7 +573,7 @@ static const struct hpt_info hpt302 __devinitdata = { | |||
555 | .chip_type = HPT302, | 573 | .chip_type = HPT302, |
556 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 574 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
557 | .dpll_clk = 66, | 575 | .dpll_clk = 66, |
558 | .settings = hpt37x_settings | 576 | .timings = &hpt37x_timings |
559 | }; | 577 | }; |
560 | 578 | ||
561 | static const struct hpt_info hpt371 __devinitdata = { | 579 | static const struct hpt_info hpt371 __devinitdata = { |
@@ -563,7 +581,7 @@ static const struct hpt_info hpt371 __devinitdata = { | |||
563 | .chip_type = HPT371, | 581 | .chip_type = HPT371, |
564 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 582 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
565 | .dpll_clk = 66, | 583 | .dpll_clk = 66, |
566 | .settings = hpt37x_settings | 584 | .timings = &hpt37x_timings |
567 | }; | 585 | }; |
568 | 586 | ||
569 | static const struct hpt_info hpt372n __devinitdata = { | 587 | static const struct hpt_info hpt372n __devinitdata = { |
@@ -571,7 +589,7 @@ static const struct hpt_info hpt372n __devinitdata = { | |||
571 | .chip_type = HPT372N, | 589 | .chip_type = HPT372N, |
572 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 590 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
573 | .dpll_clk = 77, | 591 | .dpll_clk = 77, |
574 | .settings = hpt37x_settings | 592 | .timings = &hpt37x_timings |
575 | }; | 593 | }; |
576 | 594 | ||
577 | static const struct hpt_info hpt302n __devinitdata = { | 595 | static const struct hpt_info hpt302n __devinitdata = { |
@@ -579,7 +597,7 @@ static const struct hpt_info hpt302n __devinitdata = { | |||
579 | .chip_type = HPT302N, | 597 | .chip_type = HPT302N, |
580 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 598 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
581 | .dpll_clk = 77, | 599 | .dpll_clk = 77, |
582 | .settings = hpt37x_settings | 600 | .timings = &hpt37x_timings |
583 | }; | 601 | }; |
584 | 602 | ||
585 | static const struct hpt_info hpt371n __devinitdata = { | 603 | static const struct hpt_info hpt371n __devinitdata = { |
@@ -587,7 +605,7 @@ static const struct hpt_info hpt371n __devinitdata = { | |||
587 | .chip_type = HPT371N, | 605 | .chip_type = HPT371N, |
588 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 606 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
589 | .dpll_clk = 77, | 607 | .dpll_clk = 77, |
590 | .settings = hpt37x_settings | 608 | .timings = &hpt37x_timings |
591 | }; | 609 | }; |
592 | 610 | ||
593 | static int check_in_drive_list(ide_drive_t *drive, const char **list) | 611 | static int check_in_drive_list(ide_drive_t *drive, const char **list) |
@@ -675,24 +693,21 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info) | |||
675 | for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++) | 693 | for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++) |
676 | if (xfer_speeds[i] == speed) | 694 | if (xfer_speeds[i] == speed) |
677 | break; | 695 | break; |
678 | /* | 696 | |
679 | * NOTE: info->settings only points to the pointer | 697 | return info->timings->clock_table[info->clock][i]; |
680 | * to the list of the actual register values | ||
681 | */ | ||
682 | return (*info->settings)[i]; | ||
683 | } | 698 | } |
684 | 699 | ||
685 | static void hpt36x_set_mode(ide_drive_t *drive, const u8 speed) | 700 | static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed) |
686 | { | 701 | { |
687 | ide_hwif_t *hwif = HWIF(drive); | 702 | struct pci_dev *dev = HWIF(drive)->pci_dev; |
688 | struct pci_dev *dev = hwif->pci_dev; | ||
689 | struct hpt_info *info = pci_get_drvdata(dev); | 703 | struct hpt_info *info = pci_get_drvdata(dev); |
690 | u8 itr_addr = drive->dn ? 0x44 : 0x40; | 704 | struct hpt_timings *t = info->timings; |
705 | u8 itr_addr = 0x40 + (drive->dn * 4); | ||
691 | u32 old_itr = 0; | 706 | u32 old_itr = 0; |
692 | u32 new_itr = get_speed_setting(speed, info); | 707 | u32 new_itr = get_speed_setting(speed, info); |
693 | u32 itr_mask = speed < XFER_MW_DMA_0 ? 0xc1f8ffff : | 708 | u32 itr_mask = speed < XFER_MW_DMA_0 ? t->pio_mask : |
694 | (speed < XFER_UDMA_0 ? 0x303800ff : | 709 | (speed < XFER_UDMA_0 ? t->dma_mask : |
695 | 0x30070000); | 710 | t->ultra_mask); |
696 | 711 | ||
697 | pci_read_config_dword(dev, itr_addr, &old_itr); | 712 | pci_read_config_dword(dev, itr_addr, &old_itr); |
698 | new_itr = (old_itr & ~itr_mask) | (new_itr & itr_mask); | 713 | new_itr = (old_itr & ~itr_mask) | (new_itr & itr_mask); |
@@ -705,29 +720,9 @@ static void hpt36x_set_mode(ide_drive_t *drive, const u8 speed) | |||
705 | pci_write_config_dword(dev, itr_addr, new_itr); | 720 | pci_write_config_dword(dev, itr_addr, new_itr); |
706 | } | 721 | } |
707 | 722 | ||
708 | static void hpt37x_set_mode(ide_drive_t *drive, const u8 speed) | ||
709 | { | ||
710 | ide_hwif_t *hwif = HWIF(drive); | ||
711 | struct pci_dev *dev = hwif->pci_dev; | ||
712 | struct hpt_info *info = pci_get_drvdata(dev); | ||
713 | u8 itr_addr = 0x40 + (drive->dn * 4); | ||
714 | u32 old_itr = 0; | ||
715 | u32 new_itr = get_speed_setting(speed, info); | ||
716 | u32 itr_mask = speed < XFER_MW_DMA_0 ? 0xcfc3ffff : | ||
717 | (speed < XFER_UDMA_0 ? 0x31c001ff : | ||
718 | 0x303c0000); | ||
719 | |||
720 | pci_read_config_dword(dev, itr_addr, &old_itr); | ||
721 | new_itr = (old_itr & ~itr_mask) | (new_itr & itr_mask); | ||
722 | |||
723 | if (speed < XFER_MW_DMA_0) | ||
724 | new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ | ||
725 | pci_write_config_dword(dev, itr_addr, new_itr); | ||
726 | } | ||
727 | |||
728 | static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | 723 | static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio) |
729 | { | 724 | { |
730 | HWIF(drive)->set_dma_mode(drive, XFER_PIO_0 + pio); | 725 | hpt3xx_set_mode(drive, XFER_PIO_0 + pio); |
731 | } | 726 | } |
732 | 727 | ||
733 | static int hpt3xx_quirkproc(ide_drive_t *drive) | 728 | static int hpt3xx_quirkproc(ide_drive_t *drive) |
@@ -1195,7 +1190,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha | |||
1195 | * We also don't like using the DPLL because this causes glitches | 1190 | * We also don't like using the DPLL because this causes glitches |
1196 | * on PRST-/SRST- when the state engine gets reset... | 1191 | * on PRST-/SRST- when the state engine gets reset... |
1197 | */ | 1192 | */ |
1198 | if (chip_type >= HPT374 || info->settings[clock] == NULL) { | 1193 | if (chip_type >= HPT374 || info->timings->clock_table[clock] == NULL) { |
1199 | u16 f_low, delta = pci_clk < 50 ? 2 : 4; | 1194 | u16 f_low, delta = pci_clk < 50 ? 2 : 4; |
1200 | int adjust; | 1195 | int adjust; |
1201 | 1196 | ||
@@ -1211,7 +1206,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha | |||
1211 | clock = ATA_CLOCK_50MHZ; | 1206 | clock = ATA_CLOCK_50MHZ; |
1212 | } | 1207 | } |
1213 | 1208 | ||
1214 | if (info->settings[clock] == NULL) { | 1209 | if (info->timings->clock_table[clock] == NULL) { |
1215 | printk(KERN_ERR "%s: unknown bus timing!\n", name); | 1210 | printk(KERN_ERR "%s: unknown bus timing!\n", name); |
1216 | kfree(info); | 1211 | kfree(info); |
1217 | return -EIO; | 1212 | return -EIO; |
@@ -1252,15 +1247,10 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha | |||
1252 | printk("%s: using %d MHz PCI clock\n", name, pci_clk); | 1247 | printk("%s: using %d MHz PCI clock\n", name, pci_clk); |
1253 | } | 1248 | } |
1254 | 1249 | ||
1255 | /* | ||
1256 | * Advance the table pointer to a slot which points to the list | ||
1257 | * of the register values settings matching the clock being used. | ||
1258 | */ | ||
1259 | info->settings += clock; | ||
1260 | |||
1261 | /* Store the clock frequencies. */ | 1250 | /* Store the clock frequencies. */ |
1262 | info->dpll_clk = dpll_clk; | 1251 | info->dpll_clk = dpll_clk; |
1263 | info->pci_clk = pci_clk; | 1252 | info->pci_clk = pci_clk; |
1253 | info->clock = clock; | ||
1264 | 1254 | ||
1265 | /* Point to this chip's own instance of the hpt_info structure. */ | 1255 | /* Point to this chip's own instance of the hpt_info structure. */ |
1266 | pci_set_drvdata(dev, info); | 1256 | pci_set_drvdata(dev, info); |
@@ -1304,10 +1294,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) | |||
1304 | hwif->select_data = hwif->channel ? 0x54 : 0x50; | 1294 | hwif->select_data = hwif->channel ? 0x54 : 0x50; |
1305 | 1295 | ||
1306 | hwif->set_pio_mode = &hpt3xx_set_pio_mode; | 1296 | hwif->set_pio_mode = &hpt3xx_set_pio_mode; |
1307 | if (chip_type >= HPT370) | 1297 | hwif->set_dma_mode = &hpt3xx_set_mode; |
1308 | hwif->set_dma_mode = &hpt37x_set_mode; | ||
1309 | else | ||
1310 | hwif->set_dma_mode = &hpt36x_set_mode; | ||
1311 | 1298 | ||
1312 | hwif->quirkproc = &hpt3xx_quirkproc; | 1299 | hwif->quirkproc = &hpt3xx_quirkproc; |
1313 | hwif->intrproc = &hpt3xx_intrproc; | 1300 | hwif->intrproc = &hpt3xx_intrproc; |