ata: ahci_brcm: Add support for Broadcom NSP SoC
authorYendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
Thu, 16 Jun 2016 13:53:33 +0000 (09:53 -0400)
committerTejun Heo <tj@kernel.org>
Thu, 16 Jun 2016 20:24:55 +0000 (16:24 -0400)
Add SATA3 support for Broadcom NSP SoC

Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
drivers/ata/Kconfig
drivers/ata/ahci_brcm.c

index 8fe06e6..2c8be74 100644 (file)
@@ -100,7 +100,7 @@ config SATA_AHCI_PLATFORM
 
 config AHCI_BRCM
        tristate "Broadcom AHCI SATA support"
-       depends on ARCH_BRCMSTB || BMIPS_GENERIC
+       depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP
        help
          This option enables support for the AHCI SATA3 controller found on
          Broadcom SoC's.
index e87bcec..6f8a734 100644 (file)
        (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) |         \
        (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
 
+enum brcm_ahci_version {
+       BRCM_SATA_BCM7425 = 1,
+       BRCM_SATA_BCM7445,
+       BRCM_SATA_NSP,
+};
+
 enum brcm_ahci_quirks {
        BRCM_AHCI_QUIRK_NO_NCQ          = BIT(0),
        BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1),
@@ -81,6 +87,7 @@ struct brcm_ahci_priv {
        void __iomem *top_ctrl;
        u32 port_mask;
        u32 quirks;
+       enum brcm_ahci_version version;
 };
 
 static const struct ata_port_info ahci_brcm_port_info = {
@@ -247,9 +254,19 @@ static u32 brcm_ahci_get_portmask(struct platform_device *pdev,
 
 static void brcm_sata_init(struct brcm_ahci_priv *priv)
 {
+       void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL;
+
        /* Configure endianness */
-       brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF,
-                          priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL);
+       if (priv->version ==  BRCM_SATA_NSP) {
+               u32 data = brcm_sata_readreg(ctrl);
+
+               data &= ~((0x03 << DMADATA_ENDIAN_SHIFT) |
+                       (0x03 << DMADESC_ENDIAN_SHIFT));
+               data |= (0x02 << DMADATA_ENDIAN_SHIFT) |
+                       (0x02 << DMADESC_ENDIAN_SHIFT);
+               brcm_sata_writereg(data, ctrl);
+       } else
+               brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, ctrl);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -282,8 +299,17 @@ static struct scsi_host_template ahci_platform_sht = {
        AHCI_SHT(DRV_NAME),
 };
 
+static const struct of_device_id ahci_of_match[] = {
+       {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
+       {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
+       {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
+       {},
+};
+MODULE_DEVICE_TABLE(of, ahci_of_match);
+
 static int brcm_ahci_probe(struct platform_device *pdev)
 {
+       const struct of_device_id *of_id;
        struct device *dev = &pdev->dev;
        struct brcm_ahci_priv *priv;
        struct ahci_host_priv *hpriv;
@@ -293,6 +319,12 @@ static int brcm_ahci_probe(struct platform_device *pdev)
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
+
+       of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
+       if (!of_id)
+               return -ENODEV;
+
+       priv->version = (enum brcm_ahci_version)of_id->data;
        priv->dev = dev;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
@@ -300,7 +332,8 @@ static int brcm_ahci_probe(struct platform_device *pdev)
        if (IS_ERR(priv->top_ctrl))
                return PTR_ERR(priv->top_ctrl);
 
-       if (of_device_is_compatible(dev->of_node, "brcm,bcm7425-ahci")) {
+       if ((priv->version == BRCM_SATA_BCM7425) ||
+               (priv->version == BRCM_SATA_NSP)) {
                priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ;
                priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
        }
@@ -354,13 +387,6 @@ static int brcm_ahci_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct of_device_id ahci_of_match[] = {
-       {.compatible = "brcm,bcm7425-ahci"},
-       {.compatible = "brcm,bcm7445-ahci"},
-       {},
-};
-MODULE_DEVICE_TABLE(of, ahci_of_match);
-
 static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
 
 static struct platform_driver brcm_ahci_driver = {