| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * ahci.c - AHCI SATA support |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * Copyright 2004-2005 Red Hat, Inc. |
|---|
| 9 | 10 | * |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 12 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 13 | | - * the Free Software Foundation; either version 2, or (at your option) |
|---|
| 14 | | - * any later version. |
|---|
| 15 | | - * |
|---|
| 16 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 17 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 18 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 19 | | - * GNU General Public License for more details. |
|---|
| 20 | | - * |
|---|
| 21 | | - * You should have received a copy of the GNU General Public License |
|---|
| 22 | | - * along with this program; see the file COPYING. If not, write to |
|---|
| 23 | | - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 24 | | - * |
|---|
| 25 | | - * |
|---|
| 26 | 11 | * libata documentation is available via 'make {ps|pdf}docs', |
|---|
| 27 | 12 | * as Documentation/driver-api/libata.rst |
|---|
| 28 | 13 | * |
|---|
| 29 | 14 | * AHCI hardware documentation: |
|---|
| 30 | 15 | * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf |
|---|
| 31 | 16 | * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf |
|---|
| 32 | | - * |
|---|
| 33 | 17 | */ |
|---|
| 34 | 18 | |
|---|
| 35 | 19 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 56 | 40 | enum { |
|---|
| 57 | 41 | AHCI_PCI_BAR_STA2X11 = 0, |
|---|
| 58 | 42 | AHCI_PCI_BAR_CAVIUM = 0, |
|---|
| 43 | + AHCI_PCI_BAR_LOONGSON = 0, |
|---|
| 59 | 44 | AHCI_PCI_BAR_ENMOTUS = 2, |
|---|
| 60 | 45 | AHCI_PCI_BAR_CAVIUM_GEN5 = 4, |
|---|
| 61 | 46 | AHCI_PCI_BAR_STANDARD = 5, |
|---|
| .. | .. |
|---|
| 72 | 57 | board_ahci_yes_fbs, |
|---|
| 73 | 58 | |
|---|
| 74 | 59 | /* board IDs for specific chipsets in alphabetical order */ |
|---|
| 60 | + board_ahci_al, |
|---|
| 75 | 61 | board_ahci_avn, |
|---|
| 76 | 62 | board_ahci_mcp65, |
|---|
| 77 | 63 | board_ahci_mcp77, |
|---|
| .. | .. |
|---|
| 184 | 170 | .port_ops = &ahci_ops, |
|---|
| 185 | 171 | }, |
|---|
| 186 | 172 | /* by chipsets */ |
|---|
| 173 | + [board_ahci_al] = { |
|---|
| 174 | + AHCI_HFLAGS (AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_MSI), |
|---|
| 175 | + .flags = AHCI_FLAG_COMMON, |
|---|
| 176 | + .pio_mask = ATA_PIO4, |
|---|
| 177 | + .udma_mask = ATA_UDMA6, |
|---|
| 178 | + .port_ops = &ahci_ops, |
|---|
| 179 | + }, |
|---|
| 187 | 180 | [board_ahci_avn] = { |
|---|
| 188 | 181 | .flags = AHCI_FLAG_COMMON, |
|---|
| 189 | 182 | .pio_mask = ATA_PIO4, |
|---|
| .. | .. |
|---|
| 253 | 246 | |
|---|
| 254 | 247 | static const struct pci_device_id ahci_pci_tbl[] = { |
|---|
| 255 | 248 | /* Intel */ |
|---|
| 249 | + { PCI_VDEVICE(INTEL, 0x06d6), board_ahci }, /* Comet Lake PCH-H RAID */ |
|---|
| 256 | 250 | { PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */ |
|---|
| 257 | 251 | { PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */ |
|---|
| 258 | 252 | { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */ |
|---|
| .. | .. |
|---|
| 366 | 360 | { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */ |
|---|
| 367 | 361 | { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */ |
|---|
| 368 | 362 | { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */ |
|---|
| 363 | + { PCI_VDEVICE(INTEL, 0x43d4), board_ahci }, /* Rocket Lake PCH-H RAID */ |
|---|
| 364 | + { PCI_VDEVICE(INTEL, 0x43d5), board_ahci }, /* Rocket Lake PCH-H RAID */ |
|---|
| 365 | + { PCI_VDEVICE(INTEL, 0x43d6), board_ahci }, /* Rocket Lake PCH-H RAID */ |
|---|
| 366 | + { PCI_VDEVICE(INTEL, 0x43d7), board_ahci }, /* Rocket Lake PCH-H RAID */ |
|---|
| 369 | 367 | { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */ |
|---|
| 370 | 368 | { PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */ |
|---|
| 371 | 369 | { PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */ |
|---|
| .. | .. |
|---|
| 410 | 408 | { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ |
|---|
| 411 | 409 | { PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */ |
|---|
| 412 | 410 | { PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */ |
|---|
| 411 | + { PCI_VDEVICE(INTEL, 0xa386), board_ahci }, /* Comet Lake PCH-V RAID */ |
|---|
| 413 | 412 | { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */ |
|---|
| 414 | 413 | { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */ |
|---|
| 415 | 414 | { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */ |
|---|
| 416 | 415 | { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */ |
|---|
| 417 | 416 | { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_mobile }, /* Ice Lake LP AHCI */ |
|---|
| 417 | + { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_mobile }, /* Comet Lake PCH-U AHCI */ |
|---|
| 418 | + { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_mobile }, /* Comet Lake PCH RAID */ |
|---|
| 418 | 419 | |
|---|
| 419 | 420 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
|---|
| 420 | 421 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
|---|
| .. | .. |
|---|
| 433 | 434 | { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb700 }, /* ATI SB700/800 */ |
|---|
| 434 | 435 | { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */ |
|---|
| 435 | 436 | |
|---|
| 437 | + /* Amazon's Annapurna Labs support */ |
|---|
| 438 | + { PCI_DEVICE(PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031), |
|---|
| 439 | + .class = PCI_CLASS_STORAGE_SATA_AHCI, |
|---|
| 440 | + .class_mask = 0xffffff, |
|---|
| 441 | + board_ahci_al }, |
|---|
| 436 | 442 | /* AMD */ |
|---|
| 437 | 443 | { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ |
|---|
| 438 | 444 | { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */ |
|---|
| .. | .. |
|---|
| 593 | 599 | |
|---|
| 594 | 600 | /* Enmotus */ |
|---|
| 595 | 601 | { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, |
|---|
| 602 | + |
|---|
| 603 | + /* Loongson */ |
|---|
| 604 | + { PCI_VDEVICE(LOONGSON, 0x7a08), board_ahci }, |
|---|
| 596 | 605 | |
|---|
| 597 | 606 | /* Generic, PCI class code for AHCI */ |
|---|
| 598 | 607 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
|---|
| .. | .. |
|---|
| 803 | 812 | (sstatus & 0xf) != 1) |
|---|
| 804 | 813 | break; |
|---|
| 805 | 814 | |
|---|
| 806 | | - ata_link_printk(link, KERN_INFO, "avn bounce port%d\n", |
|---|
| 807 | | - port); |
|---|
| 815 | + ata_link_info(link, "avn bounce port%d\n", port); |
|---|
| 808 | 816 | |
|---|
| 809 | 817 | pci_read_config_word(pdev, 0x92, &val); |
|---|
| 810 | 818 | val &= ~(1 << port); |
|---|
| .. | .. |
|---|
| 909 | 917 | |
|---|
| 910 | 918 | static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) |
|---|
| 911 | 919 | { |
|---|
| 920 | + const int dma_bits = using_dac ? 64 : 32; |
|---|
| 912 | 921 | int rc; |
|---|
| 913 | 922 | |
|---|
| 914 | 923 | /* |
|---|
| 915 | 924 | * If the device fixup already set the dma_mask to some non-standard |
|---|
| 916 | 925 | * value, don't extend it here. This happens on STA2X11, for example. |
|---|
| 926 | + * |
|---|
| 927 | + * XXX: manipulating the DMA mask from platform code is completely |
|---|
| 928 | + * bogus, platform code should use dev->bus_dma_limit instead.. |
|---|
| 917 | 929 | */ |
|---|
| 918 | 930 | if (pdev->dma_mask && pdev->dma_mask < DMA_BIT_MASK(32)) |
|---|
| 919 | 931 | return 0; |
|---|
| 920 | 932 | |
|---|
| 921 | | - if (using_dac && |
|---|
| 922 | | - !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) { |
|---|
| 923 | | - rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); |
|---|
| 924 | | - if (rc) { |
|---|
| 925 | | - rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); |
|---|
| 926 | | - if (rc) { |
|---|
| 927 | | - dev_err(&pdev->dev, |
|---|
| 928 | | - "64-bit DMA enable failed\n"); |
|---|
| 929 | | - return rc; |
|---|
| 930 | | - } |
|---|
| 931 | | - } |
|---|
| 932 | | - } else { |
|---|
| 933 | | - rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); |
|---|
| 934 | | - if (rc) { |
|---|
| 935 | | - dev_err(&pdev->dev, "32-bit DMA enable failed\n"); |
|---|
| 936 | | - return rc; |
|---|
| 937 | | - } |
|---|
| 938 | | - rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); |
|---|
| 939 | | - if (rc) { |
|---|
| 940 | | - dev_err(&pdev->dev, |
|---|
| 941 | | - "32-bit consistent DMA enable failed\n"); |
|---|
| 942 | | - return rc; |
|---|
| 943 | | - } |
|---|
| 944 | | - } |
|---|
| 945 | | - return 0; |
|---|
| 933 | + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(dma_bits)); |
|---|
| 934 | + if (rc) |
|---|
| 935 | + dev_err(&pdev->dev, "DMA enable failed\n"); |
|---|
| 936 | + return rc; |
|---|
| 946 | 937 | } |
|---|
| 947 | 938 | |
|---|
| 948 | 939 | static void ahci_pci_print_info(struct ata_host *host) |
|---|
| .. | .. |
|---|
| 1510 | 1501 | static void ahci_remap_check(struct pci_dev *pdev, int bar, |
|---|
| 1511 | 1502 | struct ahci_host_priv *hpriv) |
|---|
| 1512 | 1503 | { |
|---|
| 1513 | | - int i, count = 0; |
|---|
| 1504 | + int i; |
|---|
| 1514 | 1505 | u32 cap; |
|---|
| 1515 | 1506 | |
|---|
| 1516 | 1507 | /* |
|---|
| .. | .. |
|---|
| 1531 | 1522 | continue; |
|---|
| 1532 | 1523 | |
|---|
| 1533 | 1524 | /* We've found a remapped device */ |
|---|
| 1534 | | - count++; |
|---|
| 1525 | + hpriv->remapped_nvme++; |
|---|
| 1535 | 1526 | } |
|---|
| 1536 | 1527 | |
|---|
| 1537 | | - if (!count) |
|---|
| 1528 | + if (!hpriv->remapped_nvme) |
|---|
| 1538 | 1529 | return; |
|---|
| 1539 | 1530 | |
|---|
| 1540 | | - dev_warn(&pdev->dev, "Found %d remapped NVMe devices.\n", count); |
|---|
| 1531 | + dev_warn(&pdev->dev, "Found %u remapped NVMe devices.\n", |
|---|
| 1532 | + hpriv->remapped_nvme); |
|---|
| 1541 | 1533 | dev_warn(&pdev->dev, |
|---|
| 1542 | 1534 | "Switch your BIOS from RAID to AHCI mode to use them.\n"); |
|---|
| 1543 | 1535 | |
|---|
| .. | .. |
|---|
| 1657 | 1649 | } |
|---|
| 1658 | 1650 | } |
|---|
| 1659 | 1651 | |
|---|
| 1652 | +static ssize_t remapped_nvme_show(struct device *dev, |
|---|
| 1653 | + struct device_attribute *attr, |
|---|
| 1654 | + char *buf) |
|---|
| 1655 | +{ |
|---|
| 1656 | + struct ata_host *host = dev_get_drvdata(dev); |
|---|
| 1657 | + struct ahci_host_priv *hpriv = host->private_data; |
|---|
| 1658 | + |
|---|
| 1659 | + return sprintf(buf, "%u\n", hpriv->remapped_nvme); |
|---|
| 1660 | +} |
|---|
| 1661 | + |
|---|
| 1662 | +static DEVICE_ATTR_RO(remapped_nvme); |
|---|
| 1663 | + |
|---|
| 1660 | 1664 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
|---|
| 1661 | 1665 | { |
|---|
| 1662 | 1666 | unsigned int board_id = ent->driver_data; |
|---|
| .. | .. |
|---|
| 1702 | 1706 | ahci_pci_bar = AHCI_PCI_BAR_CAVIUM; |
|---|
| 1703 | 1707 | if (pdev->device == 0xa084) |
|---|
| 1704 | 1708 | ahci_pci_bar = AHCI_PCI_BAR_CAVIUM_GEN5; |
|---|
| 1709 | + } else if (pdev->vendor == PCI_VENDOR_ID_LOONGSON) { |
|---|
| 1710 | + if (pdev->device == 0x7a08) |
|---|
| 1711 | + ahci_pci_bar = AHCI_PCI_BAR_LOONGSON; |
|---|
| 1705 | 1712 | } |
|---|
| 1706 | 1713 | |
|---|
| 1707 | 1714 | /* acquire resources */ |
|---|
| .. | .. |
|---|
| 1757 | 1764 | /* detect remapped nvme devices */ |
|---|
| 1758 | 1765 | ahci_remap_check(pdev, ahci_pci_bar, hpriv); |
|---|
| 1759 | 1766 | |
|---|
| 1767 | + sysfs_add_file_to_group(&pdev->dev.kobj, |
|---|
| 1768 | + &dev_attr_remapped_nvme.attr, |
|---|
| 1769 | + NULL); |
|---|
| 1770 | + |
|---|
| 1760 | 1771 | /* must set flag prior to save config in order to take effect */ |
|---|
| 1761 | 1772 | if (ahci_broken_devslp(pdev)) |
|---|
| 1762 | 1773 | hpriv->flags |= AHCI_HFLAG_NO_DEVSLP; |
|---|
| 1763 | 1774 | |
|---|
| 1764 | 1775 | #ifdef CONFIG_ARM64 |
|---|
| 1776 | + if (pdev->vendor == PCI_VENDOR_ID_HUAWEI && |
|---|
| 1777 | + pdev->device == 0xa235 && |
|---|
| 1778 | + pdev->revision < 0x30) |
|---|
| 1779 | + hpriv->flags |= AHCI_HFLAG_NO_SXS; |
|---|
| 1780 | + |
|---|
| 1765 | 1781 | if (pdev->vendor == 0x177d && pdev->device == 0xa01c) |
|---|
| 1766 | 1782 | hpriv->irq_handler = ahci_thunderx_irq_handler; |
|---|
| 1767 | 1783 | #endif |
|---|
| .. | .. |
|---|
| 1908 | 1924 | |
|---|
| 1909 | 1925 | static void ahci_remove_one(struct pci_dev *pdev) |
|---|
| 1910 | 1926 | { |
|---|
| 1927 | + sysfs_remove_file_from_group(&pdev->dev.kobj, |
|---|
| 1928 | + &dev_attr_remapped_nvme.attr, |
|---|
| 1929 | + NULL); |
|---|
| 1911 | 1930 | pm_runtime_get_noresume(&pdev->dev); |
|---|
| 1912 | 1931 | ata_pci_remove_one(pdev); |
|---|
| 1913 | 1932 | } |
|---|