aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
authorJames Laird <jhl@mafipulation.org>2013-11-18 19:06:38 -0500
committerTejun Heo <tj@kernel.org>2013-11-23 08:34:34 -0500
commitcb85696d7277592ddbd2897db9a29f3ec6e9fe11 (patch)
tree021656b05ff51ae177992f83ba8042c7596124a8 /drivers/ata/ahci.c
parent462098b090897fbcf00088b225eb7a3adc407e98 (diff)
ahci: mcp89: enter AHCI mode under Apple BIOS emulation
Apple's BIOS emulation forcibly disables MCP89 AHCI, eg. on Macbook7,1. We can re-enable it, replacing the previous workaround of using ata_generic. tj: whitespace adjustments, dropped inline from is_mcp89_apple() Signed-off-by: James Laird <jhl@mafipulation.org> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r--drivers/ata/ahci.c60
1 files changed, 51 insertions, 9 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index e2903d03180e..c55e00562527 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -83,6 +83,8 @@ enum board_ids {
83static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); 83static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
84static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, 84static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
85 unsigned long deadline); 85 unsigned long deadline);
86static void ahci_mcp89_apple_enable(struct pci_dev *pdev);
87static bool is_mcp89_apple(struct pci_dev *pdev);
86static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, 88static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
87 unsigned long deadline); 89 unsigned long deadline);
88#ifdef CONFIG_PM 90#ifdef CONFIG_PM
@@ -659,6 +661,10 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
659 if (rc) 661 if (rc)
660 return rc; 662 return rc;
661 663
664 /* Apple BIOS helpfully mangles the registers on resume */
665 if (is_mcp89_apple(pdev))
666 ahci_mcp89_apple_enable(pdev);
667
662 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { 668 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
663 rc = ahci_pci_reset_controller(host); 669 rc = ahci_pci_reset_controller(host);
664 if (rc) 670 if (rc)
@@ -775,6 +781,48 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
775 } 781 }
776} 782}
777 783
784/*
785 * Macbook7,1 firmware forcibly disables MCP89 AHCI and changes PCI ID when
786 * booting in BIOS compatibility mode. We restore the registers but not ID.
787 */
788static void ahci_mcp89_apple_enable(struct pci_dev *pdev)
789{
790 u32 val;
791
792 printk(KERN_INFO "ahci: enabling MCP89 AHCI mode\n");
793
794 pci_read_config_dword(pdev, 0xf8, &val);
795 val |= 1 << 0x1b;
796 /* the following changes the device ID, but appears not to affect function */
797 /* val = (val & ~0xf0000000) | 0x80000000; */
798 pci_write_config_dword(pdev, 0xf8, val);
799
800 pci_read_config_dword(pdev, 0x54c, &val);
801 val |= 1 << 0xc;
802 pci_write_config_dword(pdev, 0x54c, val);
803
804 pci_read_config_dword(pdev, 0x4a4, &val);
805 val &= 0xff;
806 val |= 0x01060100;
807 pci_write_config_dword(pdev, 0x4a4, val);
808
809 pci_read_config_dword(pdev, 0x54c, &val);
810 val &= ~(1 << 0xc);
811 pci_write_config_dword(pdev, 0x54c, val);
812
813 pci_read_config_dword(pdev, 0xf8, &val);
814 val &= ~(1 << 0x1b);
815 pci_write_config_dword(pdev, 0xf8, val);
816}
817
818static bool is_mcp89_apple(struct pci_dev *pdev)
819{
820 return pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
821 pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA &&
822 pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
823 pdev->subsystem_device == 0xcb89;
824}
825
778/* only some SB600 ahci controllers can do 64bit DMA */ 826/* only some SB600 ahci controllers can do 64bit DMA */
779static bool ahci_sb600_enable_64bit(struct pci_dev *pdev) 827static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
780{ 828{
@@ -1207,15 +1255,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1207 if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable) 1255 if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable)
1208 return -ENODEV; 1256 return -ENODEV;
1209 1257
1210 /* 1258 /* Apple BIOS on MCP89 prevents us using AHCI */
1211 * For some reason, MCP89 on MacBook 7,1 doesn't work with 1259 if (is_mcp89_apple(pdev))
1212 * ahci, use ata_generic instead. 1260 ahci_mcp89_apple_enable(pdev);
1213 */
1214 if (pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
1215 pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA &&
1216 pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
1217 pdev->subsystem_device == 0xcb89)
1218 return -ENODEV;
1219 1261
1220 /* Promise's PDC42819 is a SAS/SATA controller that has an AHCI mode. 1262 /* Promise's PDC42819 is a SAS/SATA controller that has an AHCI mode.
1221 * At the moment, we can only use the AHCI mode. Let the users know 1263 * At the moment, we can only use the AHCI mode. Let the users know