diff options
Diffstat (limited to 'drivers/ata/pata_hpt3x2n.c')
-rw-r--r-- | drivers/ata/pata_hpt3x2n.c | 150 |
1 files changed, 102 insertions, 48 deletions
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 32f3463216b8..d2239bbdb798 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Libata driver for the highpoint 372N and 302N UDMA66 ATA controllers. | 2 | * Libata driver for the HighPoint 371N, 372N, and 302N UDMA66 ATA controllers. |
3 | * | 3 | * |
4 | * This driver is heavily based upon: | 4 | * This driver is heavily based upon: |
5 | * | 5 | * |
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
10 | * Portions Copyright (C) 2003 Red Hat Inc | 10 | * Portions Copyright (C) 2003 Red Hat Inc |
11 | * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. | 11 | * Portions Copyright (C) 2005-2010 MontaVista Software, Inc. |
12 | * | 12 | * |
13 | * | 13 | * |
14 | * TODO | 14 | * TODO |
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/libata.h> | 25 | #include <linux/libata.h> |
26 | 26 | ||
27 | #define DRV_NAME "pata_hpt3x2n" | 27 | #define DRV_NAME "pata_hpt3x2n" |
28 | #define DRV_VERSION "0.3.10" | 28 | #define DRV_VERSION "0.3.13" |
29 | 29 | ||
30 | enum { | 30 | enum { |
31 | HPT_PCI_FAST = (1 << 31), | 31 | HPT_PCI_FAST = (1 << 31), |
@@ -103,7 +103,7 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) | |||
103 | { | 103 | { |
104 | struct hpt_clock *clocks = hpt3x2n_clocks; | 104 | struct hpt_clock *clocks = hpt3x2n_clocks; |
105 | 105 | ||
106 | while(clocks->xfer_speed) { | 106 | while (clocks->xfer_speed) { |
107 | if (clocks->xfer_speed == speed) | 107 | if (clocks->xfer_speed == speed) |
108 | return clocks->timing; | 108 | return clocks->timing; |
109 | clocks++; | 109 | clocks++; |
@@ -113,6 +113,22 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | /** | 115 | /** |
116 | * hpt372n_filter - mode selection filter | ||
117 | * @adev: ATA device | ||
118 | * @mask: mode mask | ||
119 | * | ||
120 | * The Marvell bridge chips used on the HighPoint SATA cards do not seem | ||
121 | * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes... | ||
122 | */ | ||
123 | static unsigned long hpt372n_filter(struct ata_device *adev, unsigned long mask) | ||
124 | { | ||
125 | if (ata_id_is_sata(adev->id)) | ||
126 | mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA); | ||
127 | |||
128 | return mask; | ||
129 | } | ||
130 | |||
131 | /** | ||
116 | * hpt3x2n_cable_detect - Detect the cable type | 132 | * hpt3x2n_cable_detect - Detect the cable type |
117 | * @ap: ATA port to detect on | 133 | * @ap: ATA port to detect on |
118 | * | 134 | * |
@@ -153,6 +169,7 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline) | |||
153 | { | 169 | { |
154 | struct ata_port *ap = link->ap; | 170 | struct ata_port *ap = link->ap; |
155 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 171 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
172 | |||
156 | /* Reset the state machine */ | 173 | /* Reset the state machine */ |
157 | pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); | 174 | pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); |
158 | udelay(100); | 175 | udelay(100); |
@@ -328,10 +345,10 @@ static struct scsi_host_template hpt3x2n_sht = { | |||
328 | }; | 345 | }; |
329 | 346 | ||
330 | /* | 347 | /* |
331 | * Configuration for HPT3x2n. | 348 | * Configuration for HPT302N/371N. |
332 | */ | 349 | */ |
333 | 350 | ||
334 | static struct ata_port_operations hpt3x2n_port_ops = { | 351 | static struct ata_port_operations hpt3xxn_port_ops = { |
335 | .inherits = &ata_bmdma_port_ops, | 352 | .inherits = &ata_bmdma_port_ops, |
336 | 353 | ||
337 | .bmdma_stop = hpt3x2n_bmdma_stop, | 354 | .bmdma_stop = hpt3x2n_bmdma_stop, |
@@ -345,6 +362,15 @@ static struct ata_port_operations hpt3x2n_port_ops = { | |||
345 | .prereset = hpt3x2n_pre_reset, | 362 | .prereset = hpt3x2n_pre_reset, |
346 | }; | 363 | }; |
347 | 364 | ||
365 | /* | ||
366 | * Configuration for HPT372N. Same as 302N/371N but we have a mode filter. | ||
367 | */ | ||
368 | |||
369 | static struct ata_port_operations hpt372n_port_ops = { | ||
370 | .inherits = &hpt3xxn_port_ops, | ||
371 | .mode_filter = &hpt372n_filter, | ||
372 | }; | ||
373 | |||
348 | /** | 374 | /** |
349 | * hpt3xn_calibrate_dpll - Calibrate the DPLL loop | 375 | * hpt3xn_calibrate_dpll - Calibrate the DPLL loop |
350 | * @dev: PCI device | 376 | * @dev: PCI device |
@@ -359,12 +385,12 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev) | |||
359 | u32 reg5c; | 385 | u32 reg5c; |
360 | int tries; | 386 | int tries; |
361 | 387 | ||
362 | for(tries = 0; tries < 0x5000; tries++) { | 388 | for (tries = 0; tries < 0x5000; tries++) { |
363 | udelay(50); | 389 | udelay(50); |
364 | pci_read_config_byte(dev, 0x5b, ®5b); | 390 | pci_read_config_byte(dev, 0x5b, ®5b); |
365 | if (reg5b & 0x80) { | 391 | if (reg5b & 0x80) { |
366 | /* See if it stays set */ | 392 | /* See if it stays set */ |
367 | for(tries = 0; tries < 0x1000; tries ++) { | 393 | for (tries = 0; tries < 0x1000; tries++) { |
368 | pci_read_config_byte(dev, 0x5b, ®5b); | 394 | pci_read_config_byte(dev, 0x5b, ®5b); |
369 | /* Failed ? */ | 395 | /* Failed ? */ |
370 | if ((reg5b & 0x80) == 0) | 396 | if ((reg5b & 0x80) == 0) |
@@ -372,7 +398,7 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev) | |||
372 | } | 398 | } |
373 | /* Turn off tuning, we have the DPLL set */ | 399 | /* Turn off tuning, we have the DPLL set */ |
374 | pci_read_config_dword(dev, 0x5c, ®5c); | 400 | pci_read_config_dword(dev, 0x5c, ®5c); |
375 | pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); | 401 | pci_write_config_dword(dev, 0x5c, reg5c & ~0x100); |
376 | return 1; | 402 | return 1; |
377 | } | 403 | } |
378 | } | 404 | } |
@@ -388,8 +414,19 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) | |||
388 | 414 | ||
389 | fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */ | 415 | fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */ |
390 | if ((fcnt >> 12) != 0xABCDE) { | 416 | if ((fcnt >> 12) != 0xABCDE) { |
391 | printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n"); | 417 | int i; |
392 | return 33; /* Not BIOS set */ | 418 | u16 sr; |
419 | u32 total = 0; | ||
420 | |||
421 | printk(KERN_WARNING "pata_hpt3x2n: BIOS clock data not set.\n"); | ||
422 | |||
423 | /* This is the process the HPT371 BIOS is reported to use */ | ||
424 | for (i = 0; i < 128; i++) { | ||
425 | pci_read_config_word(pdev, 0x78, &sr); | ||
426 | total += sr & 0x1FF; | ||
427 | udelay(15); | ||
428 | } | ||
429 | fcnt = total / 128; | ||
393 | } | 430 | } |
394 | fcnt &= 0x1FF; | 431 | fcnt &= 0x1FF; |
395 | 432 | ||
@@ -431,21 +468,27 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) | |||
431 | * HPT372N 9 (HPT372N) * UDMA133 | 468 | * HPT372N 9 (HPT372N) * UDMA133 |
432 | * | 469 | * |
433 | * (1) UDMA133 support depends on the bus clock | 470 | * (1) UDMA133 support depends on the bus clock |
434 | * | ||
435 | * To pin down HPT371N | ||
436 | */ | 471 | */ |
437 | 472 | ||
438 | static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 473 | static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
439 | { | 474 | { |
440 | /* HPT372N and friends - UDMA133 */ | 475 | /* HPT372N - UDMA133 */ |
441 | static const struct ata_port_info info = { | 476 | static const struct ata_port_info info_hpt372n = { |
477 | .flags = ATA_FLAG_SLAVE_POSS, | ||
478 | .pio_mask = ATA_PIO4, | ||
479 | .mwdma_mask = ATA_MWDMA2, | ||
480 | .udma_mask = ATA_UDMA6, | ||
481 | .port_ops = &hpt372n_port_ops | ||
482 | }; | ||
483 | /* HPT302N and HPT371N - UDMA133 */ | ||
484 | static const struct ata_port_info info_hpt3xxn = { | ||
442 | .flags = ATA_FLAG_SLAVE_POSS, | 485 | .flags = ATA_FLAG_SLAVE_POSS, |
443 | .pio_mask = ATA_PIO4, | 486 | .pio_mask = ATA_PIO4, |
444 | .mwdma_mask = ATA_MWDMA2, | 487 | .mwdma_mask = ATA_MWDMA2, |
445 | .udma_mask = ATA_UDMA6, | 488 | .udma_mask = ATA_UDMA6, |
446 | .port_ops = &hpt3x2n_port_ops | 489 | .port_ops = &hpt3xxn_port_ops |
447 | }; | 490 | }; |
448 | const struct ata_port_info *ppi[] = { &info, NULL }; | 491 | const struct ata_port_info *ppi[] = { &info_hpt3xxn, NULL }; |
449 | u8 rev = dev->revision; | 492 | u8 rev = dev->revision; |
450 | u8 irqmask; | 493 | u8 irqmask; |
451 | unsigned int pci_mhz; | 494 | unsigned int pci_mhz; |
@@ -459,30 +502,36 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
459 | if (rc) | 502 | if (rc) |
460 | return rc; | 503 | return rc; |
461 | 504 | ||
462 | switch(dev->device) { | 505 | switch (dev->device) { |
463 | case PCI_DEVICE_ID_TTI_HPT366: | 506 | case PCI_DEVICE_ID_TTI_HPT366: |
464 | if (rev < 6) | 507 | /* 372N if rev >= 6 */ |
465 | return -ENODEV; | 508 | if (rev < 6) |
466 | break; | ||
467 | case PCI_DEVICE_ID_TTI_HPT371: | ||
468 | if (rev < 2) | ||
469 | return -ENODEV; | ||
470 | /* 371N if rev > 1 */ | ||
471 | break; | ||
472 | case PCI_DEVICE_ID_TTI_HPT372: | ||
473 | /* 372N if rev >= 2*/ | ||
474 | if (rev < 2) | ||
475 | return -ENODEV; | ||
476 | break; | ||
477 | case PCI_DEVICE_ID_TTI_HPT302: | ||
478 | if (rev < 2) | ||
479 | return -ENODEV; | ||
480 | break; | ||
481 | case PCI_DEVICE_ID_TTI_HPT372N: | ||
482 | break; | ||
483 | default: | ||
484 | printk(KERN_ERR "pata_hpt3x2n: PCI table is bogus please report (%d).\n", dev->device); | ||
485 | return -ENODEV; | 509 | return -ENODEV; |
510 | goto hpt372n; | ||
511 | case PCI_DEVICE_ID_TTI_HPT371: | ||
512 | /* 371N if rev >= 2 */ | ||
513 | if (rev < 2) | ||
514 | return -ENODEV; | ||
515 | break; | ||
516 | case PCI_DEVICE_ID_TTI_HPT372: | ||
517 | /* 372N if rev >= 2 */ | ||
518 | if (rev < 2) | ||
519 | return -ENODEV; | ||
520 | goto hpt372n; | ||
521 | case PCI_DEVICE_ID_TTI_HPT302: | ||
522 | /* 302N if rev >= 2 */ | ||
523 | if (rev < 2) | ||
524 | return -ENODEV; | ||
525 | break; | ||
526 | case PCI_DEVICE_ID_TTI_HPT372N: | ||
527 | hpt372n: | ||
528 | ppi[0] = &info_hpt372n; | ||
529 | break; | ||
530 | default: | ||
531 | printk(KERN_ERR | ||
532 | "pata_hpt3x2n: PCI table is bogus please report (%d).\n", | ||
533 | dev->device); | ||
534 | return -ENODEV; | ||
486 | } | 535 | } |
487 | 536 | ||
488 | /* Ok so this is a chip we support */ | 537 | /* Ok so this is a chip we support */ |
@@ -509,8 +558,10 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
509 | pci_write_config_byte(dev, 0x50, mcr1); | 558 | pci_write_config_byte(dev, 0x50, mcr1); |
510 | } | 559 | } |
511 | 560 | ||
512 | /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or | 561 | /* |
513 | 50 for UDMA100. Right now we always use 66 */ | 562 | * Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or |
563 | * 50 for UDMA100. Right now we always use 66 | ||
564 | */ | ||
514 | 565 | ||
515 | pci_mhz = hpt3x2n_pci_clock(dev); | 566 | pci_mhz = hpt3x2n_pci_clock(dev); |
516 | 567 | ||
@@ -522,7 +573,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
522 | pci_write_config_byte(dev, 0x5B, 0x21); | 573 | pci_write_config_byte(dev, 0x5B, 0x21); |
523 | 574 | ||
524 | /* Unlike the 37x we don't try jiggling the frequency */ | 575 | /* Unlike the 37x we don't try jiggling the frequency */ |
525 | for(adjust = 0; adjust < 8; adjust++) { | 576 | for (adjust = 0; adjust < 8; adjust++) { |
526 | if (hpt3xn_calibrate_dpll(dev)) | 577 | if (hpt3xn_calibrate_dpll(dev)) |
527 | break; | 578 | break; |
528 | pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); | 579 | pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); |
@@ -534,8 +585,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
534 | 585 | ||
535 | printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n", | 586 | printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n", |
536 | pci_mhz); | 587 | pci_mhz); |
537 | /* Set our private data up. We only need a few flags so we use | 588 | |
538 | it directly */ | 589 | /* |
590 | * Set our private data up. We only need a few flags | ||
591 | * so we use it directly. | ||
592 | */ | ||
539 | if (pci_mhz > 60) | 593 | if (pci_mhz > 60) |
540 | hpriv = (void *)(PCI66 | USE_DPLL); | 594 | hpriv = (void *)(PCI66 | USE_DPLL); |
541 | 595 | ||
@@ -562,9 +616,9 @@ static const struct pci_device_id hpt3x2n[] = { | |||
562 | }; | 616 | }; |
563 | 617 | ||
564 | static struct pci_driver hpt3x2n_pci_driver = { | 618 | static struct pci_driver hpt3x2n_pci_driver = { |
565 | .name = DRV_NAME, | 619 | .name = DRV_NAME, |
566 | .id_table = hpt3x2n, | 620 | .id_table = hpt3x2n, |
567 | .probe = hpt3x2n_init_one, | 621 | .probe = hpt3x2n_init_one, |
568 | .remove = ata_pci_remove_one | 622 | .remove = ata_pci_remove_one |
569 | }; | 623 | }; |
570 | 624 | ||
@@ -579,7 +633,7 @@ static void __exit hpt3x2n_exit(void) | |||
579 | } | 633 | } |
580 | 634 | ||
581 | MODULE_AUTHOR("Alan Cox"); | 635 | MODULE_AUTHOR("Alan Cox"); |
582 | MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3x2n/30x"); | 636 | MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3xxN"); |
583 | MODULE_LICENSE("GPL"); | 637 | MODULE_LICENSE("GPL"); |
584 | MODULE_DEVICE_TABLE(pci, hpt3x2n); | 638 | MODULE_DEVICE_TABLE(pci, hpt3x2n); |
585 | MODULE_VERSION(DRV_VERSION); | 639 | MODULE_VERSION(DRV_VERSION); |