|
@@ -8,6 +8,7 @@
|
|
|
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
|
|
|
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
|
|
|
* Portions Copyright (C) 2003 Red Hat Inc
|
|
|
+ * Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
|
|
|
*
|
|
|
* TODO
|
|
|
* PLL mode
|
|
@@ -25,7 +26,7 @@
|
|
|
#include <linux/libata.h>
|
|
|
|
|
|
#define DRV_NAME "pata_hpt37x"
|
|
|
-#define DRV_VERSION "0.6.0"
|
|
|
+#define DRV_VERSION "0.6.4"
|
|
|
|
|
|
struct hpt_clock {
|
|
|
u8 xfer_speed;
|
|
@@ -61,201 +62,75 @@ struct hpt_chip {
|
|
|
* 31 FIFO enable.
|
|
|
*/
|
|
|
|
|
|
-/* from highpoint documentation. these are old values */
|
|
|
-static const struct hpt_clock hpt370_timings_33[] = {
|
|
|
-/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */
|
|
|
- { XFER_UDMA_5, 0x16454e31 },
|
|
|
- { XFER_UDMA_4, 0x16454e31 },
|
|
|
- { XFER_UDMA_3, 0x166d4e31 },
|
|
|
- { XFER_UDMA_2, 0x16494e31 },
|
|
|
- { XFER_UDMA_1, 0x164d4e31 },
|
|
|
- { XFER_UDMA_0, 0x16514e31 },
|
|
|
-
|
|
|
- { XFER_MW_DMA_2, 0x26514e21 },
|
|
|
- { XFER_MW_DMA_1, 0x26514e33 },
|
|
|
- { XFER_MW_DMA_0, 0x26514e97 },
|
|
|
-
|
|
|
- { XFER_PIO_4, 0x06514e21 },
|
|
|
- { XFER_PIO_3, 0x06514e22 },
|
|
|
- { XFER_PIO_2, 0x06514e33 },
|
|
|
- { XFER_PIO_1, 0x06914e43 },
|
|
|
- { XFER_PIO_0, 0x06914e57 },
|
|
|
- { 0, 0x06514e57 }
|
|
|
+static struct hpt_clock hpt37x_timings_33[] = {
|
|
|
+ { XFER_UDMA_6, 0x12446231 }, /* 0x12646231 ?? */
|
|
|
+ { XFER_UDMA_5, 0x12446231 },
|
|
|
+ { XFER_UDMA_4, 0x12446231 },
|
|
|
+ { XFER_UDMA_3, 0x126c6231 },
|
|
|
+ { XFER_UDMA_2, 0x12486231 },
|
|
|
+ { XFER_UDMA_1, 0x124c6233 },
|
|
|
+ { XFER_UDMA_0, 0x12506297 },
|
|
|
+
|
|
|
+ { XFER_MW_DMA_2, 0x22406c31 },
|
|
|
+ { XFER_MW_DMA_1, 0x22406c33 },
|
|
|
+ { XFER_MW_DMA_0, 0x22406c97 },
|
|
|
+
|
|
|
+ { XFER_PIO_4, 0x06414e31 },
|
|
|
+ { XFER_PIO_3, 0x06414e42 },
|
|
|
+ { XFER_PIO_2, 0x06414e53 },
|
|
|
+ { XFER_PIO_1, 0x06814e93 },
|
|
|
+ { XFER_PIO_0, 0x06814ea7 }
|
|
|
};
|
|
|
|
|
|
-static const struct hpt_clock hpt370_timings_66[] = {
|
|
|
- { XFER_UDMA_5, 0x14846231 },
|
|
|
- { XFER_UDMA_4, 0x14886231 },
|
|
|
- { XFER_UDMA_3, 0x148c6231 },
|
|
|
- { XFER_UDMA_2, 0x148c6231 },
|
|
|
- { XFER_UDMA_1, 0x14906231 },
|
|
|
- { XFER_UDMA_0, 0x14986231 },
|
|
|
-
|
|
|
- { XFER_MW_DMA_2, 0x26514e21 },
|
|
|
- { XFER_MW_DMA_1, 0x26514e33 },
|
|
|
- { XFER_MW_DMA_0, 0x26514e97 },
|
|
|
-
|
|
|
- { XFER_PIO_4, 0x06514e21 },
|
|
|
- { XFER_PIO_3, 0x06514e22 },
|
|
|
- { XFER_PIO_2, 0x06514e33 },
|
|
|
- { XFER_PIO_1, 0x06914e43 },
|
|
|
- { XFER_PIO_0, 0x06914e57 },
|
|
|
- { 0, 0x06514e57 }
|
|
|
+static struct hpt_clock hpt37x_timings_50[] = {
|
|
|
+ { XFER_UDMA_6, 0x12848242 },
|
|
|
+ { XFER_UDMA_5, 0x12848242 },
|
|
|
+ { XFER_UDMA_4, 0x12ac8242 },
|
|
|
+ { XFER_UDMA_3, 0x128c8242 },
|
|
|
+ { XFER_UDMA_2, 0x120c8242 },
|
|
|
+ { XFER_UDMA_1, 0x12148254 },
|
|
|
+ { XFER_UDMA_0, 0x121882ea },
|
|
|
+
|
|
|
+ { XFER_MW_DMA_2, 0x22808242 },
|
|
|
+ { XFER_MW_DMA_1, 0x22808254 },
|
|
|
+ { XFER_MW_DMA_0, 0x228082ea },
|
|
|
+
|
|
|
+ { XFER_PIO_4, 0x0a81f442 },
|
|
|
+ { XFER_PIO_3, 0x0a81f443 },
|
|
|
+ { XFER_PIO_2, 0x0a81f454 },
|
|
|
+ { XFER_PIO_1, 0x0ac1f465 },
|
|
|
+ { XFER_PIO_0, 0x0ac1f48a }
|
|
|
};
|
|
|
|
|
|
-/* these are the current (4 sep 2001) timings from highpoint */
|
|
|
-static const struct hpt_clock hpt370a_timings_33[] = {
|
|
|
- { XFER_UDMA_5, 0x12446231 },
|
|
|
- { XFER_UDMA_4, 0x12446231 },
|
|
|
- { XFER_UDMA_3, 0x126c6231 },
|
|
|
- { XFER_UDMA_2, 0x12486231 },
|
|
|
- { XFER_UDMA_1, 0x124c6233 },
|
|
|
- { XFER_UDMA_0, 0x12506297 },
|
|
|
-
|
|
|
- { XFER_MW_DMA_2, 0x22406c31 },
|
|
|
- { XFER_MW_DMA_1, 0x22406c33 },
|
|
|
- { XFER_MW_DMA_0, 0x22406c97 },
|
|
|
-
|
|
|
- { XFER_PIO_4, 0x06414e31 },
|
|
|
- { XFER_PIO_3, 0x06414e42 },
|
|
|
- { XFER_PIO_2, 0x06414e53 },
|
|
|
- { XFER_PIO_1, 0x06814e93 },
|
|
|
- { XFER_PIO_0, 0x06814ea7 },
|
|
|
- { 0, 0x06814ea7 }
|
|
|
+static struct hpt_clock hpt37x_timings_66[] = {
|
|
|
+ { XFER_UDMA_6, 0x1c869c62 },
|
|
|
+ { XFER_UDMA_5, 0x1cae9c62 }, /* 0x1c8a9c62 */
|
|
|
+ { XFER_UDMA_4, 0x1c8a9c62 },
|
|
|
+ { XFER_UDMA_3, 0x1c8e9c62 },
|
|
|
+ { XFER_UDMA_2, 0x1c929c62 },
|
|
|
+ { XFER_UDMA_1, 0x1c9a9c62 },
|
|
|
+ { XFER_UDMA_0, 0x1c829c62 },
|
|
|
+
|
|
|
+ { XFER_MW_DMA_2, 0x2c829c62 },
|
|
|
+ { XFER_MW_DMA_1, 0x2c829c66 },
|
|
|
+ { XFER_MW_DMA_0, 0x2c829d2e },
|
|
|
+
|
|
|
+ { XFER_PIO_4, 0x0c829c62 },
|
|
|
+ { XFER_PIO_3, 0x0c829c84 },
|
|
|
+ { XFER_PIO_2, 0x0c829ca6 },
|
|
|
+ { XFER_PIO_1, 0x0d029d26 },
|
|
|
+ { XFER_PIO_0, 0x0d029d5e }
|
|
|
};
|
|
|
|
|
|
-/* 2x 33MHz timings */
|
|
|
-static const struct hpt_clock hpt370a_timings_66[] = {
|
|
|
- { XFER_UDMA_5, 0x1488e673 },
|
|
|
- { XFER_UDMA_4, 0x1488e673 },
|
|
|
- { XFER_UDMA_3, 0x1498e673 },
|
|
|
- { XFER_UDMA_2, 0x1490e673 },
|
|
|
- { XFER_UDMA_1, 0x1498e677 },
|
|
|
- { XFER_UDMA_0, 0x14a0e73f },
|
|
|
-
|
|
|
- { XFER_MW_DMA_2, 0x2480fa73 },
|
|
|
- { XFER_MW_DMA_1, 0x2480fa77 },
|
|
|
- { XFER_MW_DMA_0, 0x2480fb3f },
|
|
|
-
|
|
|
- { XFER_PIO_4, 0x0c82be73 },
|
|
|
- { XFER_PIO_3, 0x0c82be95 },
|
|
|
- { XFER_PIO_2, 0x0c82beb7 },
|
|
|
- { XFER_PIO_1, 0x0d02bf37 },
|
|
|
- { XFER_PIO_0, 0x0d02bf5f },
|
|
|
- { 0, 0x0d02bf5f }
|
|
|
-};
|
|
|
-
|
|
|
-static const struct hpt_clock hpt370a_timings_50[] = {
|
|
|
- { XFER_UDMA_5, 0x12848242 },
|
|
|
- { XFER_UDMA_4, 0x12ac8242 },
|
|
|
- { XFER_UDMA_3, 0x128c8242 },
|
|
|
- { XFER_UDMA_2, 0x120c8242 },
|
|
|
- { XFER_UDMA_1, 0x12148254 },
|
|
|
- { XFER_UDMA_0, 0x121882ea },
|
|
|
-
|
|
|
- { XFER_MW_DMA_2, 0x22808242 },
|
|
|
- { XFER_MW_DMA_1, 0x22808254 },
|
|
|
- { XFER_MW_DMA_0, 0x228082ea },
|
|
|
-
|
|
|
- { XFER_PIO_4, 0x0a81f442 },
|
|
|
- { XFER_PIO_3, 0x0a81f443 },
|
|
|
- { XFER_PIO_2, 0x0a81f454 },
|
|
|
- { XFER_PIO_1, 0x0ac1f465 },
|
|
|
- { XFER_PIO_0, 0x0ac1f48a },
|
|
|
- { 0, 0x0ac1f48a }
|
|
|
-};
|
|
|
-
|
|
|
-static const struct hpt_clock hpt372_timings_33[] = {
|
|
|
- { XFER_UDMA_6, 0x1c81dc62 },
|
|
|
- { XFER_UDMA_5, 0x1c6ddc62 },
|
|
|
- { XFER_UDMA_4, 0x1c8ddc62 },
|
|
|
- { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */
|
|
|
- { XFER_UDMA_2, 0x1c91dc62 },
|
|
|
- { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */
|
|
|
- { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */
|
|
|
-
|
|
|
- { XFER_MW_DMA_2, 0x2c829262 },
|
|
|
- { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */
|
|
|
- { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */
|
|
|
-
|
|
|
- { XFER_PIO_4, 0x0c829c62 },
|
|
|
- { XFER_PIO_3, 0x0c829c84 },
|
|
|
- { XFER_PIO_2, 0x0c829ca6 },
|
|
|
- { XFER_PIO_1, 0x0d029d26 },
|
|
|
- { XFER_PIO_0, 0x0d029d5e },
|
|
|
- { 0, 0x0d029d5e }
|
|
|
-};
|
|
|
-
|
|
|
-static const struct hpt_clock hpt372_timings_50[] = {
|
|
|
- { XFER_UDMA_5, 0x12848242 },
|
|
|
- { XFER_UDMA_4, 0x12ac8242 },
|
|
|
- { XFER_UDMA_3, 0x128c8242 },
|
|
|
- { XFER_UDMA_2, 0x120c8242 },
|
|
|
- { XFER_UDMA_1, 0x12148254 },
|
|
|
- { XFER_UDMA_0, 0x121882ea },
|
|
|
-
|
|
|
- { XFER_MW_DMA_2, 0x22808242 },
|
|
|
- { XFER_MW_DMA_1, 0x22808254 },
|
|
|
- { XFER_MW_DMA_0, 0x228082ea },
|
|
|
-
|
|
|
- { XFER_PIO_4, 0x0a81f442 },
|
|
|
- { XFER_PIO_3, 0x0a81f443 },
|
|
|
- { XFER_PIO_2, 0x0a81f454 },
|
|
|
- { XFER_PIO_1, 0x0ac1f465 },
|
|
|
- { XFER_PIO_0, 0x0ac1f48a },
|
|
|
- { 0, 0x0a81f443 }
|
|
|
-};
|
|
|
-
|
|
|
-static const struct hpt_clock hpt372_timings_66[] = {
|
|
|
- { XFER_UDMA_6, 0x1c869c62 },
|
|
|
- { XFER_UDMA_5, 0x1cae9c62 },
|
|
|
- { XFER_UDMA_4, 0x1c8a9c62 },
|
|
|
- { XFER_UDMA_3, 0x1c8e9c62 },
|
|
|
- { XFER_UDMA_2, 0x1c929c62 },
|
|
|
- { XFER_UDMA_1, 0x1c9a9c62 },
|
|
|
- { XFER_UDMA_0, 0x1c829c62 },
|
|
|
-
|
|
|
- { XFER_MW_DMA_2, 0x2c829c62 },
|
|
|
- { XFER_MW_DMA_1, 0x2c829c66 },
|
|
|
- { XFER_MW_DMA_0, 0x2c829d2e },
|
|
|
-
|
|
|
- { XFER_PIO_4, 0x0c829c62 },
|
|
|
- { XFER_PIO_3, 0x0c829c84 },
|
|
|
- { XFER_PIO_2, 0x0c829ca6 },
|
|
|
- { XFER_PIO_1, 0x0d029d26 },
|
|
|
- { XFER_PIO_0, 0x0d029d5e },
|
|
|
- { 0, 0x0d029d26 }
|
|
|
-};
|
|
|
-
|
|
|
-static const struct hpt_clock hpt374_timings_33[] = {
|
|
|
- { XFER_UDMA_6, 0x12808242 },
|
|
|
- { XFER_UDMA_5, 0x12848242 },
|
|
|
- { XFER_UDMA_4, 0x12ac8242 },
|
|
|
- { XFER_UDMA_3, 0x128c8242 },
|
|
|
- { XFER_UDMA_2, 0x120c8242 },
|
|
|
- { XFER_UDMA_1, 0x12148254 },
|
|
|
- { XFER_UDMA_0, 0x121882ea },
|
|
|
-
|
|
|
- { XFER_MW_DMA_2, 0x22808242 },
|
|
|
- { XFER_MW_DMA_1, 0x22808254 },
|
|
|
- { XFER_MW_DMA_0, 0x228082ea },
|
|
|
-
|
|
|
- { XFER_PIO_4, 0x0a81f442 },
|
|
|
- { XFER_PIO_3, 0x0a81f443 },
|
|
|
- { XFER_PIO_2, 0x0a81f454 },
|
|
|
- { XFER_PIO_1, 0x0ac1f465 },
|
|
|
- { XFER_PIO_0, 0x0ac1f48a },
|
|
|
- { 0, 0x06814e93 }
|
|
|
-};
|
|
|
|
|
|
static const struct hpt_chip hpt370 = {
|
|
|
"HPT370",
|
|
|
48,
|
|
|
{
|
|
|
- hpt370_timings_33,
|
|
|
+ hpt37x_timings_33,
|
|
|
NULL,
|
|
|
NULL,
|
|
|
- hpt370_timings_66
|
|
|
+ hpt37x_timings_66
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -263,10 +138,10 @@ static const struct hpt_chip hpt370a = {
|
|
|
"HPT370A",
|
|
|
48,
|
|
|
{
|
|
|
- hpt370a_timings_33,
|
|
|
+ hpt37x_timings_33,
|
|
|
NULL,
|
|
|
- hpt370a_timings_50,
|
|
|
- hpt370a_timings_66
|
|
|
+ hpt37x_timings_50,
|
|
|
+ hpt37x_timings_66
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -274,10 +149,10 @@ static const struct hpt_chip hpt372 = {
|
|
|
"HPT372",
|
|
|
55,
|
|
|
{
|
|
|
- hpt372_timings_33,
|
|
|
+ hpt37x_timings_33,
|
|
|
NULL,
|
|
|
- hpt372_timings_50,
|
|
|
- hpt372_timings_66
|
|
|
+ hpt37x_timings_50,
|
|
|
+ hpt37x_timings_66
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -285,10 +160,10 @@ static const struct hpt_chip hpt302 = {
|
|
|
"HPT302",
|
|
|
66,
|
|
|
{
|
|
|
- hpt372_timings_33,
|
|
|
+ hpt37x_timings_33,
|
|
|
NULL,
|
|
|
- hpt372_timings_50,
|
|
|
- hpt372_timings_66
|
|
|
+ hpt37x_timings_50,
|
|
|
+ hpt37x_timings_66
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -296,10 +171,10 @@ static const struct hpt_chip hpt371 = {
|
|
|
"HPT371",
|
|
|
66,
|
|
|
{
|
|
|
- hpt372_timings_33,
|
|
|
+ hpt37x_timings_33,
|
|
|
NULL,
|
|
|
- hpt372_timings_50,
|
|
|
- hpt372_timings_66
|
|
|
+ hpt37x_timings_50,
|
|
|
+ hpt37x_timings_66
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -307,10 +182,10 @@ static const struct hpt_chip hpt372a = {
|
|
|
"HPT372A",
|
|
|
66,
|
|
|
{
|
|
|
- hpt372_timings_33,
|
|
|
+ hpt37x_timings_33,
|
|
|
NULL,
|
|
|
- hpt372_timings_50,
|
|
|
- hpt372_timings_66
|
|
|
+ hpt37x_timings_50,
|
|
|
+ hpt37x_timings_66
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -318,7 +193,7 @@ static const struct hpt_chip hpt374 = {
|
|
|
"HPT374",
|
|
|
48,
|
|
|
{
|
|
|
- hpt374_timings_33,
|
|
|
+ hpt37x_timings_33,
|
|
|
NULL,
|
|
|
NULL,
|
|
|
NULL
|
|
@@ -462,8 +337,7 @@ static int hpt37x_pre_reset(struct ata_port *ap)
|
|
|
ap->cbl = ATA_CBL_PATA80;
|
|
|
|
|
|
/* Reset the state machine */
|
|
|
- pci_write_config_byte(pdev, 0x50, 0x37);
|
|
|
- pci_write_config_byte(pdev, 0x54, 0x37);
|
|
|
+ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
|
|
udelay(100);
|
|
|
|
|
|
return ata_std_prereset(ap);
|
|
@@ -513,8 +387,7 @@ static int hpt374_pre_reset(struct ata_port *ap)
|
|
|
ap->cbl = ATA_CBL_PATA80;
|
|
|
|
|
|
/* Reset the state machine */
|
|
|
- pci_write_config_byte(pdev, 0x50, 0x37);
|
|
|
- pci_write_config_byte(pdev, 0x54, 0x37);
|
|
|
+ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
|
|
udelay(100);
|
|
|
|
|
|
return ata_std_prereset(ap);
|
|
@@ -1032,6 +905,24 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
.udma_mask = 0x3f,
|
|
|
.port_ops = &hpt370a_port_ops
|
|
|
};
|
|
|
+ /* HPT370 - UDMA100 */
|
|
|
+ static struct ata_port_info info_hpt370_33 = {
|
|
|
+ .sht = &hpt37x_sht,
|
|
|
+ .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
|
|
|
+ .pio_mask = 0x1f,
|
|
|
+ .mwdma_mask = 0x07,
|
|
|
+ .udma_mask = 0x0f,
|
|
|
+ .port_ops = &hpt370_port_ops
|
|
|
+ };
|
|
|
+ /* HPT370A - UDMA100 */
|
|
|
+ static struct ata_port_info info_hpt370a_33 = {
|
|
|
+ .sht = &hpt37x_sht,
|
|
|
+ .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
|
|
|
+ .pio_mask = 0x1f,
|
|
|
+ .mwdma_mask = 0x07,
|
|
|
+ .udma_mask = 0x0f,
|
|
|
+ .port_ops = &hpt370a_port_ops
|
|
|
+ };
|
|
|
/* HPT371, 372 and friends - UDMA133 */
|
|
|
static struct ata_port_info info_hpt372 = {
|
|
|
.sht = &hpt37x_sht,
|
|
@@ -1067,7 +958,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
|
|
|
u8 irqmask;
|
|
|
u32 class_rev;
|
|
|
+ u8 mcr1;
|
|
|
u32 freq;
|
|
|
+ int prefer_dpll = 1;
|
|
|
+
|
|
|
+ unsigned long iobase = pci_resource_start(dev, 4);
|
|
|
|
|
|
const struct hpt_chip *chip_table;
|
|
|
int clock_slot;
|
|
@@ -1088,10 +983,12 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
case 3:
|
|
|
port = &info_hpt370;
|
|
|
chip_table = &hpt370;
|
|
|
+ prefer_dpll = 0;
|
|
|
break;
|
|
|
case 4:
|
|
|
port = &info_hpt370a;
|
|
|
chip_table = &hpt370a;
|
|
|
+ prefer_dpll = 0;
|
|
|
break;
|
|
|
case 5:
|
|
|
port = &info_hpt372;
|
|
@@ -1119,8 +1016,16 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
chip_table = &hpt302;
|
|
|
break;
|
|
|
case PCI_DEVICE_ID_TTI_HPT371:
|
|
|
+ if (class_rev > 1)
|
|
|
+ return -ENODEV;
|
|
|
port = &info_hpt372;
|
|
|
chip_table = &hpt371;
|
|
|
+ /* Single channel device, paster is not present
|
|
|
+ but the NIOS (or us for non x86) must mark it
|
|
|
+ absent */
|
|
|
+ pci_read_config_byte(dev, 0x50, &mcr1);
|
|
|
+ mcr1 &= ~0x04;
|
|
|
+ pci_write_config_byte(dev, 0x50, mcr1);
|
|
|
break;
|
|
|
case PCI_DEVICE_ID_TTI_HPT374:
|
|
|
chip_table = &hpt374;
|
|
@@ -1150,8 +1055,18 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
*/
|
|
|
|
|
|
pci_write_config_byte(dev, 0x5b, 0x23);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * HighPoint does this for HPT372A.
|
|
|
+ * NOTE: This register is only writeable via I/O space.
|
|
|
+ */
|
|
|
+ if (chip_table == &hpt372a)
|
|
|
+ outb(0x0e, iobase + 0x9c);
|
|
|
|
|
|
- pci_read_config_dword(dev, 0x70, &freq);
|
|
|
+ /* Some devices do not let this value be accessed via PCI space
|
|
|
+ according to the old driver */
|
|
|
+
|
|
|
+ freq = inl(iobase + 0x90);
|
|
|
if ((freq >> 12) != 0xABCDE) {
|
|
|
int i;
|
|
|
u8 sr;
|
|
@@ -1162,7 +1077,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
/* This is the process the HPT371 BIOS is reported to use */
|
|
|
for(i = 0; i < 128; i++) {
|
|
|
pci_read_config_byte(dev, 0x78, &sr);
|
|
|
- total += sr;
|
|
|
+ total += sr & 0x1FF;
|
|
|
udelay(15);
|
|
|
}
|
|
|
freq = total / 128;
|
|
@@ -1173,15 +1088,27 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
* Turn the frequency check into a band and then find a timing
|
|
|
* table to match it.
|
|
|
*/
|
|
|
-
|
|
|
+
|
|
|
clock_slot = hpt37x_clock_slot(freq, chip_table->base);
|
|
|
- if (chip_table->clocks[clock_slot] == NULL) {
|
|
|
+ if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) {
|
|
|
/*
|
|
|
* We need to try PLL mode instead
|
|
|
+ *
|
|
|
+ * For non UDMA133 capable devices we should
|
|
|
+ * use a 50MHz DPLL by choice
|
|
|
*/
|
|
|
- unsigned int f_low = (MHz[clock_slot] * chip_table->base) / 192;
|
|
|
- unsigned int f_high = f_low + 2;
|
|
|
+ unsigned int f_low, f_high;
|
|
|
int adjust;
|
|
|
+
|
|
|
+ clock_slot = 2;
|
|
|
+ if (port->udma_mask & 0xE0)
|
|
|
+ clock_slot = 3;
|
|
|
+
|
|
|
+ f_low = (MHz[clock_slot] * chip_table->base) / 192;
|
|
|
+ f_high = f_low + 2;
|
|
|
+
|
|
|
+ /* Select the DPLL clock. */
|
|
|
+ pci_write_config_byte(dev, 0x5b, 0x21);
|
|
|
|
|
|
for(adjust = 0; adjust < 8; adjust++) {
|
|
|
if (hpt37x_calibrate_dpll(dev))
|
|
@@ -1197,15 +1124,17 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
- /* Check if this works for all cases */
|
|
|
- port->private_data = (void *)hpt370_timings_66;
|
|
|
+ if (clock_slot == 3)
|
|
|
+ port->private_data = (void *)hpt37x_timings_66;
|
|
|
+ else
|
|
|
+ port->private_data = (void *)hpt37x_timings_50;
|
|
|
|
|
|
printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
|
|
|
} else {
|
|
|
port->private_data = (void *)chip_table->clocks[clock_slot];
|
|
|
/*
|
|
|
* Perform a final fixup. The 371 and 372 clock determines
|
|
|
- * if UDMA133 is available.
|
|
|
+ * if UDMA133 is available. (FIXME: should we use DPLL then ?)
|
|
|
*/
|
|
|
|
|
|
if (clock_slot == 2 && chip_table == &hpt372) { /* 50Mhz */
|
|
@@ -1214,8 +1143,13 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|
|
port = &info_hpt372_50;
|
|
|
else BUG();
|
|
|
}
|
|
|
+ if (clock_slot < 2 && port == &info_hpt370)
|
|
|
+ port = &info_hpt370_33;
|
|
|
+ if (clock_slot < 2 && port == &info_hpt370a)
|
|
|
+ port = &info_hpt370a_33;
|
|
|
printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
|
|
|
}
|
|
|
+
|
|
|
port_info[0] = port_info[1] = port;
|
|
|
/* Now kick off ATA set up */
|
|
|
return ata_pci_init_one(dev, port_info, 2);
|