aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ata_piix.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-01-18 04:36:30 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:16 -0500
commitc729072459446885c5c200137de1db32da5db4dc (patch)
treefeaa1b07055f397282704a4da0590a9b07b4415f /drivers/ata/ata_piix.c
parent8b09f0da0f873698a7e8b329dfb7b10fd42d5cdf (diff)
ata_piix: implement SIDPR SCR access
For ICH8, SCRs can be accessed using index and data register pair located at BAR 5. This patch implements support for it such that PHY status, errors and hardreset are available for those controllers. This is the only case where two devices on a PATA channel have access to SCRs and creates a unique problem of mapping two SCRs to one link. Note that this is different from PMP case in that they aren't quite separate links - e.g. softreset resets both devices. This problem is worked around by merging the SCR values. To upper layer, it looks like there is a single link with one set of SCRs but with two devices. This works well enough for PHY event, error reporting and hardreset. Supporting hardreset is important because in rare cases SATA devices fail to recover without it after PHY errors. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r--drivers/ata/ata_piix.c251
1 files changed, 247 insertions, 4 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 024e6d52eab2..a65c8ae5c461 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -101,9 +101,14 @@ enum {
101 ICH5_PMR = 0x90, /* port mapping register */ 101 ICH5_PMR = 0x90, /* port mapping register */
102 ICH5_PCS = 0x92, /* port control and status */ 102 ICH5_PCS = 0x92, /* port control and status */
103 PIIX_SCC = 0x0A, /* sub-class code register */ 103 PIIX_SCC = 0x0A, /* sub-class code register */
104 PIIX_SIDPR_BAR = 5,
105 PIIX_SIDPR_LEN = 16,
106 PIIX_SIDPR_IDX = 0,
107 PIIX_SIDPR_DATA = 4,
104 108
105 PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ 109 PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */
106 PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ 110 PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */
111 PIIX_FLAG_SIDPR = (1 << 29), /* SATA idx/data pair regs */
107 112
108 PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, 113 PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS,
109 PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, 114 PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR,
@@ -152,6 +157,7 @@ struct piix_map_db {
152 157
153struct piix_host_priv { 158struct piix_host_priv {
154 const int *map; 159 const int *map;
160 void __iomem *sidpr;
155}; 161};
156 162
157static int piix_init_one(struct pci_dev *pdev, 163static int piix_init_one(struct pci_dev *pdev,
@@ -162,6 +168,9 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
162static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); 168static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev);
163static int ich_pata_cable_detect(struct ata_port *ap); 169static int ich_pata_cable_detect(struct ata_port *ap);
164static u8 piix_vmw_bmdma_status(struct ata_port *ap); 170static u8 piix_vmw_bmdma_status(struct ata_port *ap);
171static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val);
172static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val);
173static void piix_sidpr_error_handler(struct ata_port *ap);
165#ifdef CONFIG_PM 174#ifdef CONFIG_PM
166static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); 175static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
167static int piix_pci_device_resume(struct pci_dev *pdev); 176static int piix_pci_device_resume(struct pci_dev *pdev);
@@ -411,6 +420,35 @@ static const struct ata_port_operations piix_vmw_ops = {
411 .port_start = ata_port_start, 420 .port_start = ata_port_start,
412}; 421};
413 422
423static const struct ata_port_operations piix_sidpr_sata_ops = {
424 .tf_load = ata_tf_load,
425 .tf_read = ata_tf_read,
426 .check_status = ata_check_status,
427 .exec_command = ata_exec_command,
428 .dev_select = ata_std_dev_select,
429
430 .bmdma_setup = ata_bmdma_setup,
431 .bmdma_start = ata_bmdma_start,
432 .bmdma_stop = ata_bmdma_stop,
433 .bmdma_status = ata_bmdma_status,
434 .qc_prep = ata_qc_prep,
435 .qc_issue = ata_qc_issue_prot,
436 .data_xfer = ata_data_xfer,
437
438 .scr_read = piix_sidpr_scr_read,
439 .scr_write = piix_sidpr_scr_write,
440
441 .freeze = ata_bmdma_freeze,
442 .thaw = ata_bmdma_thaw,
443 .error_handler = piix_sidpr_error_handler,
444 .post_internal_cmd = ata_bmdma_post_internal_cmd,
445
446 .irq_clear = ata_bmdma_irq_clear,
447 .irq_on = ata_irq_on,
448
449 .port_start = ata_port_start,
450};
451
414static const struct piix_map_db ich5_map_db = { 452static const struct piix_map_db ich5_map_db = {
415 .mask = 0x7, 453 .mask = 0x7,
416 .port_enable = 0x3, 454 .port_enable = 0x3,
@@ -598,7 +636,8 @@ static struct ata_port_info piix_port_info[] = {
598 636
599 [ich8_sata_ahci] = 637 [ich8_sata_ahci] =
600 { 638 {
601 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, 639 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI |
640 PIIX_FLAG_SIDPR,
602 .pio_mask = 0x1f, /* pio0-4 */ 641 .pio_mask = 0x1f, /* pio0-4 */
603 .mwdma_mask = 0x07, /* mwdma0-2 */ 642 .mwdma_mask = 0x07, /* mwdma0-2 */
604 .udma_mask = ATA_UDMA6, 643 .udma_mask = ATA_UDMA6,
@@ -607,7 +646,8 @@ static struct ata_port_info piix_port_info[] = {
607 646
608 [ich8_2port_sata] = 647 [ich8_2port_sata] =
609 { 648 {
610 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, 649 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI |
650 PIIX_FLAG_SIDPR,
611 .pio_mask = 0x1f, /* pio0-4 */ 651 .pio_mask = 0x1f, /* pio0-4 */
612 .mwdma_mask = 0x07, /* mwdma0-2 */ 652 .mwdma_mask = 0x07, /* mwdma0-2 */
613 .udma_mask = ATA_UDMA6, 653 .udma_mask = ATA_UDMA6,
@@ -625,7 +665,8 @@ static struct ata_port_info piix_port_info[] = {
625 665
626 [ich8m_apple_sata_ahci] = 666 [ich8m_apple_sata_ahci] =
627 { 667 {
628 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, 668 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI |
669 PIIX_FLAG_SIDPR,
629 .pio_mask = 0x1f, /* pio0-4 */ 670 .pio_mask = 0x1f, /* pio0-4 */
630 .mwdma_mask = 0x07, /* mwdma0-2 */ 671 .mwdma_mask = 0x07, /* mwdma0-2 */
631 .udma_mask = ATA_UDMA6, 672 .udma_mask = ATA_UDMA6,
@@ -974,6 +1015,180 @@ static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev)
974 do_pata_set_dmamode(ap, adev, 1); 1015 do_pata_set_dmamode(ap, adev, 1);
975} 1016}
976 1017
1018/*
1019 * Serial ATA Index/Data Pair Superset Registers access
1020 *
1021 * Beginning from ICH8, there's a sane way to access SCRs using index
1022 * and data register pair located at BAR5. This creates an
1023 * interesting problem of mapping two SCRs to one port.
1024 *
1025 * Although they have separate SCRs, the master and slave aren't
1026 * independent enough to be treated as separate links - e.g. softreset
1027 * resets both. Also, there's no protocol defined for hard resetting
1028 * singled device sharing the virtual port (no defined way to acquire
1029 * device signature). This is worked around by merging the SCR values
1030 * into one sensible value and requesting follow-up SRST after
1031 * hardreset.
1032 *
1033 * SCR merging is perfomed in nibbles which is the unit contents in
1034 * SCRs are organized. If two values are equal, the value is used.
1035 * When they differ, merge table which lists precedence of possible
1036 * values is consulted and the first match or the last entry when
1037 * nothing matches is used. When there's no merge table for the
1038 * specific nibble, value from the first port is used.
1039 */
1040static const int piix_sidx_map[] = {
1041 [SCR_STATUS] = 0,
1042 [SCR_ERROR] = 2,
1043 [SCR_CONTROL] = 1,
1044};
1045
1046static void piix_sidpr_sel(struct ata_device *dev, unsigned int reg)
1047{
1048 struct ata_port *ap = dev->link->ap;
1049 struct piix_host_priv *hpriv = ap->host->private_data;
1050
1051 iowrite32(((ap->port_no * 2 + dev->devno) << 8) | piix_sidx_map[reg],
1052 hpriv->sidpr + PIIX_SIDPR_IDX);
1053}
1054
1055static int piix_sidpr_read(struct ata_device *dev, unsigned int reg)
1056{
1057 struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
1058
1059 piix_sidpr_sel(dev, reg);
1060 return ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
1061}
1062
1063static void piix_sidpr_write(struct ata_device *dev, unsigned int reg, u32 val)
1064{
1065 struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
1066
1067 piix_sidpr_sel(dev, reg);
1068 iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
1069}
1070
1071u32 piix_merge_scr(u32 val0, u32 val1, const int * const *merge_tbl)
1072{
1073 u32 val = 0;
1074 int i, mi;
1075
1076 for (i = 0, mi = 0; i < 32 / 4; i++) {
1077 u8 c0 = (val0 >> (i * 4)) & 0xf;
1078 u8 c1 = (val1 >> (i * 4)) & 0xf;
1079 u8 merged = c0;
1080 const int *cur;
1081
1082 /* if no merge preference, assume the first value */
1083 cur = merge_tbl[mi];
1084 if (!cur)
1085 goto done;
1086 mi++;
1087
1088 /* if two values equal, use it */
1089 if (c0 == c1)
1090 goto done;
1091
1092 /* choose the first match or the last from the merge table */
1093 while (*cur != -1) {
1094 if (c0 == *cur || c1 == *cur)
1095 break;
1096 cur++;
1097 }
1098 if (*cur == -1)
1099 cur--;
1100 merged = *cur;
1101 done:
1102 val |= merged << (i * 4);
1103 }
1104
1105 return val;
1106}
1107
1108static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val)
1109{
1110 const int * const sstatus_merge_tbl[] = {
1111 /* DET */ (const int []){ 1, 3, 0, 4, 3, -1 },
1112 /* SPD */ (const int []){ 2, 1, 0, -1 },
1113 /* IPM */ (const int []){ 6, 2, 1, 0, -1 },
1114 NULL,
1115 };
1116 const int * const scontrol_merge_tbl[] = {
1117 /* DET */ (const int []){ 1, 0, 4, 0, -1 },
1118 /* SPD */ (const int []){ 0, 2, 1, 0, -1 },
1119 /* IPM */ (const int []){ 0, 1, 2, 3, 0, -1 },
1120 NULL,
1121 };
1122 u32 v0, v1;
1123
1124 if (reg >= ARRAY_SIZE(piix_sidx_map))
1125 return -EINVAL;
1126
1127 if (!(ap->flags & ATA_FLAG_SLAVE_POSS)) {
1128 *val = piix_sidpr_read(&ap->link.device[0], reg);
1129 return 0;
1130 }
1131
1132 v0 = piix_sidpr_read(&ap->link.device[0], reg);
1133 v1 = piix_sidpr_read(&ap->link.device[1], reg);
1134
1135 switch (reg) {
1136 case SCR_STATUS:
1137 *val = piix_merge_scr(v0, v1, sstatus_merge_tbl);
1138 break;
1139 case SCR_ERROR:
1140 *val = v0 | v1;
1141 break;
1142 case SCR_CONTROL:
1143 *val = piix_merge_scr(v0, v1, scontrol_merge_tbl);
1144 break;
1145 }
1146
1147 return 0;
1148}
1149
1150static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val)
1151{
1152 if (reg >= ARRAY_SIZE(piix_sidx_map))
1153 return -EINVAL;
1154
1155 piix_sidpr_write(&ap->link.device[0], reg, val);
1156
1157 if (ap->flags & ATA_FLAG_SLAVE_POSS)
1158 piix_sidpr_write(&ap->link.device[1], reg, val);
1159
1160 return 0;
1161}
1162
1163static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class,
1164 unsigned long deadline)
1165{
1166 const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
1167 int rc;
1168
1169 /* do hardreset */
1170 rc = sata_link_hardreset(link, timing, deadline);
1171 if (rc) {
1172 ata_link_printk(link, KERN_ERR,
1173 "COMRESET failed (errno=%d)\n", rc);
1174 return rc;
1175 }
1176
1177 /* TODO: phy layer with polling, timeouts, etc. */
1178 if (ata_link_offline(link)) {
1179 *class = ATA_DEV_NONE;
1180 return 0;
1181 }
1182
1183 return -EAGAIN;
1184}
1185
1186static void piix_sidpr_error_handler(struct ata_port *ap)
1187{
1188 ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
1189 piix_sidpr_hardreset, ata_std_postreset);
1190}
1191
977#ifdef CONFIG_PM 1192#ifdef CONFIG_PM
978static int piix_broken_suspend(void) 1193static int piix_broken_suspend(void)
979{ 1194{
@@ -1304,6 +1519,32 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev,
1304 return map; 1519 return map;
1305} 1520}
1306 1521
1522static void __devinit piix_init_sidpr(struct ata_host *host)
1523{
1524 struct pci_dev *pdev = to_pci_dev(host->dev);
1525 struct piix_host_priv *hpriv = host->private_data;
1526 int i;
1527
1528 /* check for availability */
1529 for (i = 0; i < 4; i++)
1530 if (hpriv->map[i] == IDE)
1531 return;
1532
1533 if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR))
1534 return;
1535
1536 if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 ||
1537 pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN)
1538 return;
1539
1540 if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME))
1541 return;
1542
1543 hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
1544 host->ports[0]->ops = &piix_sidpr_sata_ops;
1545 host->ports[1]->ops = &piix_sidpr_sata_ops;
1546}
1547
1307static void piix_iocfg_bit18_quirk(struct pci_dev *pdev) 1548static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
1308{ 1549{
1309 static const struct dmi_system_id sysids[] = { 1550 static const struct dmi_system_id sysids[] = {
@@ -1408,8 +1649,10 @@ static int piix_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1408 } 1649 }
1409 } 1650 }
1410 1651
1411 if (port_flags & ATA_FLAG_SATA) 1652 if (port_flags & ATA_FLAG_SATA) {
1412 piix_init_pcs(host, piix_map_db_table[ent->driver_data]); 1653 piix_init_pcs(host, piix_map_db_table[ent->driver_data]);
1654 piix_init_sidpr(host);
1655 }
1413 1656
1414 /* apply IOCFG bit18 quirk */ 1657 /* apply IOCFG bit18 quirk */
1415 piix_iocfg_bit18_quirk(pdev); 1658 piix_iocfg_bit18_quirk(pdev);